-
-
Notifications
You must be signed in to change notification settings - Fork 313
feat: Redesign and fix entire manage roles page #4625
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughConverted domain listing to a four-column table with client-side delete form submission. Rebuilt roles UI into a single manage-roles page with Add/Edit modals, client-side modal handlers, and consolidated roles table. Server view refactored to enforce permissions and handle add/update/remove role actions with richer context. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor U as User
participant B as Browser
participant S as Server (ManageRolesView)
participant DB as Data Store
rect rgb(242,248,255)
note over U,B: Load Manage Roles (GET)
U->>B: Navigate to manage-roles
B->>S: GET /manage-roles
S->>DB: Fetch org, current_user_role, roles, domains, users
S-->>B: 200 HTML (roles table, modals, context)
end
rect rgb(245,255,250)
note over U,B: Add Role (modal)
U->>B: Open & submit Add Role
B->>S: POST action=add_role
S->>S: Validate permissions, duplicates, self-assignment
S->>DB: Create role
S-->>B: Redirect/response with outcome
end
rect rgb(255,250,240)
note over U,B: Edit Role (modal)
U->>B: Open & submit Edit Role
B->>S: POST action=update_role
S->>S: Validate (no self/owner modification)
S->>DB: Update role
S-->>B: Redirect/response with outcome
end
rect rgb(255,240,245)
note over U,B: Remove Role (confirm)
U->>B: Click Remove, confirm
B->>S: POST action=remove_role
S->>S: Validate (no self/owner removal)
S->>DB: Deactivate role
S-->>B: Redirect/response with outcome
end
sequenceDiagram
autonumber
actor U as User
participant B as Browser
participant T as Domains JS
participant S as Server (Domains Endpoint)
U->>B: Click "Delete" on domain row
B->>T: Trigger confirmDelete(domainId, domainName)
T->>U: Browser confirm dialog (custom)
alt Confirmed
T->>S: Submit dynamic form (DELETE via domain route)
S-->>T: Redirect/response with outcome
else Canceled
T-->>U: No action
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
website/templates/organization/dashboard/organization_manage_domains.html
Fixed
Show fixed
Hide fixed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
website/views/company.py (3)
659-661: Expose is_active to template.Needed for Manage Domains status badge.
- domains = domains_query.values( - "id", "name", "url", "logo", "has_security_txt", "security_txt_checked_at" - ).order_by("name") + domains = domains_query.values( + "id", "name", "url", "logo", "is_active", "has_security_txt", "security_txt_checked_at" + ).order_by("name")
930-938: Authorization gap: ensure domain belongs to the organization before deleting.Currently any member could delete a domain from another org by ID. Enforce org match.
def delete(self, request, id, *args, **kwargs): domain_id = request.POST.get("domain_id", None) - domain = get_object_or_404(Domain, id=domain_id) + domain = get_object_or_404(Domain, id=domain_id) if domain is None: messages.error(request, "Domain not found.") return redirect("organization_manage_domains", id=id) + if domain.organization_id != id: + messages.error(request, "You do not have permission to delete this domain.") + return redirect("organization_manage_domains", id=id) domain.delete() messages.success(request, "Domain deleted successfully") return redirect("organization_manage_domains", id=id)
878-879: Don’t disable TLS verification.verify=False weakens security and can hide MITM. Use default verification.
- response = requests.get(safe_url, timeout=5, verify=False) + response = requests.get(safe_url, timeout=5)
🧹 Nitpick comments (4)
website/views/company.py (4)
695-697: Remove debug print.Leftover print floods stdout.
- elif method == "put": - print("*" * 100) - return self.put(request, *args, **kwargs) + elif method == "put": + return self.put(request, *args, **kwargs)
1341-1344: Robustly extract organization email domain from URL.urlparse(...).netloc is empty for bare domains like example.com. Fall back to path.
- organization_url = organization_obj.url - parsed_url = urlparse(organization_url).netloc - organization_domain = parsed_url.replace("www.", "").strip() + organization_url = organization_obj.url or "" + parsed = urlparse(organization_url) + host = (parsed.netloc or parsed.path or "").strip() + organization_domain = host.replace("www.", "").strip().lower()
1485-1488: Improve exception handling and logging.Avoid broad Exception and use logger.exception for stack traces.
- except User.DoesNotExist: - messages.error(request, "User not found or inactive") - except Exception as e: - logger.error(f"Error adding role: {str(e)}") - messages.error(request, "An error occurred while adding the role. Please try again.") + except User.DoesNotExist: + messages.error(request, "User not found or inactive") + except Exception: + logger.exception("Error adding role") + messages.error(request, "An error occurred while adding the role. Please try again.") @@ - except OrganizationAdmin.DoesNotExist: - messages.error(request, "Role not found") - except Exception as e: - logger.error(f"Error updating role: {str(e)}") - messages.error(request, "An error occurred while updating the role. Please try again.") + except OrganizationAdmin.DoesNotExist: + messages.error(request, "Role not found") + except Exception: + logger.exception("Error updating role") + messages.error(request, "An error occurred while updating the role. Please try again.") @@ - except OrganizationAdmin.DoesNotExist: - messages.error(request, "Role not found") - except Exception as e: - logger.error(f"Error removing role: {str(e)}") - messages.error(request, "An error occurred while removing the role. Please try again.") + except OrganizationAdmin.DoesNotExist: + messages.error(request, "Role not found") + except Exception: + logger.exception("Error removing role") + messages.error(request, "An error occurred while removing the role. Please try again.")As per coding guidelines and static analysis
Also applies to: 1523-1526, 1551-1554
1413-1413: Nit: Remove unused args/kwargs in post.Silences ARG002 and clarifies signature.
- def post(self, request, id, *args, **kwargs): + def post(self, request, id, *_args, **_kwargs):
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting
📒 Files selected for processing (3)
website/templates/organization/dashboard/organization_manage_domains.html(3 hunks)website/templates/organization/dashboard/organization_manage_roles.html(1 hunks)website/views/company.py(2 hunks)
🧰 Additional context used
🪛 GitHub Check: CodeQL
website/templates/organization/dashboard/organization_manage_roles.html
[warning] 348-352: DOM text reinterpreted as HTML
DOM text is reinterpreted as HTML without escaping meta-characters.
website/templates/organization/dashboard/organization_manage_domains.html
[warning] 173-177: DOM text reinterpreted as HTML
DOM text is reinterpreted as HTML without escaping meta-characters.
🪛 Ruff (0.14.0)
website/views/company.py
1413-1413: Unused method argument: args
(ARG002)
1413-1413: Unused method argument: kwargs
(ARG002)
1485-1485: Do not catch blind exception: Exception
(BLE001)
1486-1486: Use logging.exception instead of logging.error
Replace with exception
(TRY400)
1486-1486: Use explicit conversion flag
Replace with conversion flag
(RUF010)
1523-1523: Do not catch blind exception: Exception
(BLE001)
1524-1524: Use logging.exception instead of logging.error
Replace with exception
(TRY400)
1524-1524: Use explicit conversion flag
Replace with conversion flag
(RUF010)
1551-1551: Do not catch blind exception: Exception
(BLE001)
1552-1552: Use logging.exception instead of logging.error
Replace with exception
(TRY400)
1552-1552: Use explicit conversion flag
Replace with conversion flag
(RUF010)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Run Tests
🔇 Additional comments (1)
website/templates/organization/dashboard/organization_manage_roles.html (1)
304-379: Verified: base template defines {% block scripts %}.
website/templates/organization/dashboard/organization_manage_domains.html
Show resolved
Hide resolved
website/templates/organization/dashboard/organization_manage_domains.html
Outdated
Show resolved
Hide resolved
website/templates/organization/dashboard/organization_manage_domains.html
Show resolved
Hide resolved
website/templates/organization/dashboard/organization_manage_roles.html
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
♻️ Duplicate comments (2)
website/templates/organization/dashboard/organization_manage_domains.html (2)
81-85: Status badge remains broken:is_activestill missing from context.This issue was previously flagged. The template checks
domain.is_active, butOrganizationDashboardManageDomainsView.get(lines 659-661 inwebsite/views/company.py) returns domains viavalues(...)without includingis_active, so this condition is always false.Apply this diff to
website/views/company.pyto fix:domains = domains_query.values( - "id", "name", "url", "logo", "has_security_txt", "security_txt_checked_at" + "id", "name", "url", "logo", "is_active", "has_security_txt", "security_txt_checked_at" ).order_by("name")
165-183: Fix innerHTML DOM injection risk flagged by CodeQL.Using
innerHTMLto inject form fields (lines 174-178) is a security risk. Even though inputs appear benign, any unescaped content incsrfTokenordomainIdcould be interpreted as HTML/script tags.Based on static analysis
Apply this diff to use
createElementinstead:function confirmDelete(domainId, domainName) { - if (confirm(`Are you sure you want to delete ${domainName}? This action cannot be undone.`)) { + if (!confirm(`Are you sure you want to delete ${domainName}? This action cannot be undone.`)) return; + const form = document.createElement('form'); form.method = 'post'; form.action = '{% url "add_domain" organization %}'; const csrfElement = document.querySelector('[name=csrfmiddlewaretoken]'); const csrfToken = csrfElement ? csrfElement.value : '{{ csrf_token|escapejs }}'; - form.innerHTML = ` - <input type="hidden" name="csrfmiddlewaretoken" value="${csrfToken}"> - <input type="hidden" name="_method" value="delete"> - <input type="hidden" name="domain_id" value="${domainId}"> - `; + const csrfField = document.createElement('input'); + csrfField.type = 'hidden'; + csrfField.name = 'csrfmiddlewaretoken'; + csrfField.value = csrfToken; + + const methodField = document.createElement('input'); + methodField.type = 'hidden'; + methodField.name = '_method'; + methodField.value = 'delete'; + + const idField = document.createElement('input'); + idField.type = 'hidden'; + idField.name = 'domain_id'; + idField.value = String(domainId); + + form.append(csrfField, methodField, idField); document.body.appendChild(form); form.submit(); - } }
🧹 Nitpick comments (3)
website/views/company.py (3)
1338-1369: Consider the heuristic nature of email domain matching.The code extracts the domain from
organization.url(lines 1341-1346) and matches users with emails ending in@{domain}(lines 1350-1354). This heuristic assumes the organization's URL domain matches their email domain, which may not always be true (e.g., URLexample.combut emails@exampleinc.com).The fallback to all active users (lines 1357-1362, 1365-1369) mitigates this limitation, but consider:
- Adding an explicit
email_domainfield to the Organization model for precise matching- Or documenting this heuristic behavior for users
1416-1416: Remove unused method parameters.The
argsandkwargsparameters are not used in this method.Based on static analysis
Apply this diff:
- def post(self, request, id, *args, **kwargs): + def post(self, request, id):
1459-1466: Consider reactivating inactive roles instead of creating duplicates.The check at lines 1459-1466 only looks for existing active roles. If a user previously had a role that was deactivated (via
remove_role), this logic will create a newOrganizationAdminrecord, leaving the inactive one orphaned.Consider reactivating existing inactive roles:
# Check for existing roles (active or inactive) existing_role = OrganizationAdmin.objects.filter( user=user, organization=organization_obj ).first() if existing_role: if existing_role.is_active: messages.error(request, f"{user.username} already has an active role in this organization") return redirect("organization_manage_roles", id=id) else: # Reactivate and update the existing role existing_role.is_active = True existing_role.role = int(role) existing_role.domain = domain existing_role.save() messages.success(request, f"Reactivated and updated role for {user.username}") return redirect("organization_manage_roles", id=id)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting
📒 Files selected for processing (2)
website/templates/organization/dashboard/organization_manage_domains.html(3 hunks)website/views/company.py(2 hunks)
🧰 Additional context used
🪛 GitHub Check: CodeQL
website/templates/organization/dashboard/organization_manage_domains.html
[warning] 173-177: DOM text reinterpreted as HTML
DOM text is reinterpreted as HTML without escaping meta-characters.
🪛 Ruff (0.14.0)
website/views/company.py
1416-1416: Unused method argument: args
(ARG002)
1416-1416: Unused method argument: kwargs
(ARG002)
1488-1488: Do not catch blind exception: Exception
(BLE001)
1489-1489: Use logging.exception instead of logging.error
Replace with exception
(TRY400)
1489-1489: Use explicit conversion flag
Replace with conversion flag
(RUF010)
1526-1526: Do not catch blind exception: Exception
(BLE001)
1527-1527: Use logging.exception instead of logging.error
Replace with exception
(TRY400)
1527-1527: Use explicit conversion flag
Replace with conversion flag
(RUF010)
1554-1554: Do not catch blind exception: Exception
(BLE001)
1555-1555: Use logging.exception instead of logging.error
Replace with exception
(TRY400)
1555-1555: Use explicit conversion flag
Replace with conversion flag
(RUF010)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Run Tests
🔇 Additional comments (3)
website/views/company.py (3)
1303-1329: LGTM! Thorough permission checks.The permission logic correctly:
- Verifies user is admin or manager (lines 1304-1309)
- Retrieves the user's role level via
OrganizationAdmin(lines 1312-1323)- Restricts role management to admins only (lines 1325-1328)
- Grants full access to organization owners even without an explicit role
1371-1399: LGTM! Clean data formatting.The role data assembly is thorough and handles edge cases:
- Safely accesses
user.userprofilewithhasattrcheck (lines 1383-1385)- Marks organization owner roles (line 1392)
- Provides role counts for UI display (lines 1396-1399)
1546-1548: LGTM! Soft delete approach is good for audit trail.Deactivating roles (
is_active = False) instead of hard-deleting preserves the audit trail and allows potential reactivation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Nitpick comments (2)
website/views/company.py (2)
1341-1369: Consider limiting available_users query scope.The fallback logic fetches up to 100 active users when no organization domain match exists. For large user bases, this could be inefficient or expose unnecessary user data.
Consider adding a search/autocomplete interface instead of pre-loading all users, or further restricting the fallback query (e.g., users who have interacted with the organization).
1416-1416: Remove unused method arguments.The
argsandkwargsparameters are unused in the POST method signature.Based on static analysis
Apply this diff:
- def post(self, request, id, *args, **kwargs): + def post(self, request, id):
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting
📒 Files selected for processing (2)
website/templates/organization/dashboard/organization_manage_roles.html(1 hunks)website/views/company.py(4 hunks)
🧰 Additional context used
🪛 Ruff (0.14.0)
website/views/company.py
1416-1416: Unused method argument: args
(ARG002)
1416-1416: Unused method argument: kwargs
(ARG002)
1489-1489: Redundant exception object included in logging.exception call
(TRY401)
1527-1527: Use logging.exception instead of logging.error
Replace with exception
(TRY400)
1527-1527: Use explicit conversion flag
Replace with conversion flag
(RUF010)
1530-1530: Use logging.exception instead of logging.error
Replace with exception
(TRY400)
1530-1530: Use explicit conversion flag
Replace with conversion flag
(RUF010)
1533-1533: Use logging.exception instead of logging.error
Replace with exception
(TRY400)
1533-1533: Use explicit conversion flag
Replace with conversion flag
(RUF010)
1564-1564: Redundant exception object included in logging.exception call
(TRY401)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Run Tests
- GitHub Check: docker-test
🔇 Additional comments (7)
website/templates/organization/dashboard/organization_manage_roles.html (4)
107-149: LGTM! Action visibility logic now correctly prevents owner/self edits.The conditional logic at line 107 (
{% if not role.is_owner and role.user_id != request.user.id %}) properly blocks editing both owner roles and the current user's own role. Theescapejsfilter on lines 108 and 120 correctly mitigates XSS risks when passing usernames to JavaScript.
339-382: LGTM! DOM manipulation hardened with createElement.The function now:
- Sanitizes the username for display (line 341)
- Robustly finds the CSRF token with error handling (lines 345-349)
- Uses
createElementand.valueassignment instead ofinnerHTML(lines 357-377)This addresses the CodeQL warning about DOM text reinterpretation.
Based on static analysis
385-402: LGTM! Accessibility features implemented.The modal close handlers for Escape key (lines 387-392) and overlay clicks (lines 395-401) improve keyboard navigation and user experience.
108-108: Fix role value handling in JavaScript call.When
role.roleis falsy,|default:"null"produces the string"null"instead of JavaScript'snull, causing type mismatches.Apply this diff:
-<button onclick="openEditRoleModal({{ role.id }}, '{{ role.username|escapejs }}', {{ role.role|default:"null" }}, {% if role.domain_id %}{{ role.domain_id }}{% else %}null{% endif %})" +<button onclick="openEditRoleModal({{ role.id }}, '{{ role.username|escapejs }}', {{ role.role|default:0 }}, {% if role.domain_id %}{{ role.domain_id }}{% else %}null{% endif %})"Likely an incorrect or invalid review comment.
website/views/company.py (3)
1303-1329: LGTM! Permission checks are comprehensive and correctly enforced.The permission logic:
- Verifies user is org admin or manager (lines 1304-1309)
- Retrieves current user's role level (lines 1312-1323)
- Only allows admins (role=0) or org owner to manage roles (lines 1326-1328)
This properly restricts role management to authorized users.
1443-1491: LGTM! Role addition logic includes proper safeguards.The add_role action:
- Accepts either user_id or email (lines 1451-1457)
- Prevents duplicate roles (lines 1460-1466)
- Prevents self-assignment (lines 1469-1471)
- Handles optional domain assignment (lines 1474-1476)
- Uses specific exception types instead of blind catch-all
1539-1566: LGTM! Role removal safely deactivates instead of deleting.The remove_role action:
- Prevents removing own role (lines 1546-1548)
- Prevents removing owner's role (lines 1551-1553)
- Deactivates role instead of deleting (lines 1556-1557), preserving audit trail
| except (ValidationError, IntegrityError) as e: | ||
| logger.exception(f"Error adding role: {e!s}") | ||
| messages.error(request, "An error occurred while adding the role. Please try again.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix redundant exception in logging.exception call.
Line 1489 includes {e!s} when logger.exception already includes the exception info automatically.
Based on static analysis
Apply this diff:
- except (ValidationError, IntegrityError) as e:
- logger.exception(f"Error adding role: {e!s}")
+ except (ValidationError, IntegrityError):
+ logger.exception("Error adding role")📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| except (ValidationError, IntegrityError) as e: | |
| logger.exception(f"Error adding role: {e!s}") | |
| messages.error(request, "An error occurred while adding the role. Please try again.") | |
| except (ValidationError, IntegrityError): | |
| logger.exception("Error adding role") | |
| messages.error(request, "An error occurred while adding the role. Please try again.") |
🧰 Tools
🪛 Ruff (0.14.0)
1489-1489: Redundant exception object included in logging.exception call
(TRY401)
🤖 Prompt for AI Agents
In website/views/company.py around lines 1488 to 1490, remove the redundant
{e!s} from the logger.exception f-string; change the call to simply
logger.exception("Error adding role") (or logger.exception("Error adding role:
%s", e) if you prefer an inline message) so the exception info is not duplicated
and the stacktrace is still logged automatically.
| except OrganizationAdmin.DoesNotExist: | ||
| messages.error(request, "Role not found") | ||
| except ValueError as e: | ||
| logger.error(f"Invalid value provided when updating role: {str(e)}") | ||
| messages.error(request, str(e)) | ||
| except ValidationError as e: | ||
| logger.error(f"Validation error when updating role: {str(e)}") | ||
| messages.error(request, str(e)) | ||
| except IntegrityError as e: | ||
| logger.error(f"Database integrity error when updating role: {str(e)}") | ||
| messages.error(request, "Database integrity error: Unable to update role due to conflicting data") | ||
| except Exception as e: | ||
| logger.exception("Error updating role") | ||
| messages.error(request, "An error occurred while updating the role. " + str(e)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Improve exception logging consistency.
Lines 1527, 1530, 1533 use logger.error instead of logger.exception, preventing traceback capture. The final catch-all (line 1536) correctly uses logger.exception.
Based on static analysis
Apply this diff:
except OrganizationAdmin.DoesNotExist:
messages.error(request, "Role not found")
except ValueError as e:
- logger.error(f"Invalid value provided when updating role: {str(e)}")
+ logger.exception("Invalid value provided when updating role")
messages.error(request, str(e))
except ValidationError as e:
- logger.error(f"Validation error when updating role: {str(e)}")
+ logger.exception("Validation error when updating role")
messages.error(request, str(e))
except IntegrityError as e:
- logger.error(f"Database integrity error when updating role: {str(e)}")
+ logger.exception("Database integrity error when updating role")
messages.error(request, "Database integrity error: Unable to update role due to conflicting data")
except Exception as e:
logger.exception("Error updating role")
messages.error(request, "An error occurred while updating the role. " + str(e))📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| except OrganizationAdmin.DoesNotExist: | |
| messages.error(request, "Role not found") | |
| except ValueError as e: | |
| logger.error(f"Invalid value provided when updating role: {str(e)}") | |
| messages.error(request, str(e)) | |
| except ValidationError as e: | |
| logger.error(f"Validation error when updating role: {str(e)}") | |
| messages.error(request, str(e)) | |
| except IntegrityError as e: | |
| logger.error(f"Database integrity error when updating role: {str(e)}") | |
| messages.error(request, "Database integrity error: Unable to update role due to conflicting data") | |
| except Exception as e: | |
| logger.exception("Error updating role") | |
| messages.error(request, "An error occurred while updating the role. " + str(e)) | |
| except OrganizationAdmin.DoesNotExist: | |
| messages.error(request, "Role not found") | |
| except ValueError as e: | |
| logger.exception("Invalid value provided when updating role") | |
| messages.error(request, str(e)) | |
| except ValidationError as e: | |
| logger.exception("Validation error when updating role") | |
| messages.error(request, str(e)) | |
| except IntegrityError as e: | |
| logger.exception("Database integrity error when updating role") | |
| messages.error(request, "Database integrity error: Unable to update role due to conflicting data") | |
| except Exception as e: | |
| logger.exception("Error updating role") | |
| messages.error(request, "An error occurred while updating the role. " + str(e)) |
🧰 Tools
🪛 Ruff (0.14.0)
1527-1527: Use logging.exception instead of logging.error
Replace with exception
(TRY400)
1527-1527: Use explicit conversion flag
Replace with conversion flag
(RUF010)
1530-1530: Use logging.exception instead of logging.error
Replace with exception
(TRY400)
1530-1530: Use explicit conversion flag
Replace with conversion flag
(RUF010)
1533-1533: Use logging.exception instead of logging.error
Replace with exception
(TRY400)
1533-1533: Use explicit conversion flag
Replace with conversion flag
(RUF010)
🤖 Prompt for AI Agents
In website/views/company.py around lines 1524 to 1537, the specific except
blocks for ValueError (line ~1527), ValidationError (line ~1530) and
IntegrityError (line ~1533) use logger.error which prevents tracebacks from
being captured; change those three logger.error calls to logger.exception so the
stack traces are logged while leaving the user-facing messages unchanged, and
keep the final generic except using logger.exception as is.
| except (ValidationError, ValueError) as e: | ||
| logger.exception(f"Error removing role: {e!s}") | ||
| messages.error(request, "An error occurred while removing the role. Please try again.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix redundant exception in logging.exception call.
Line 1564 includes {e!s} when logger.exception already includes the exception info automatically.
Based on static analysis
Apply this diff:
- except (ValidationError, ValueError) as e:
- logger.exception(f"Error removing role: {e!s}")
+ except (ValidationError, ValueError):
+ logger.exception("Error removing role")📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| except (ValidationError, ValueError) as e: | |
| logger.exception(f"Error removing role: {e!s}") | |
| messages.error(request, "An error occurred while removing the role. Please try again.") | |
| except (ValidationError, ValueError): | |
| logger.exception("Error removing role") | |
| messages.error(request, "An error occurred while removing the role. Please try again.") |
🧰 Tools
🪛 Ruff (0.14.0)
1564-1564: Redundant exception object included in logging.exception call
(TRY401)
🤖 Prompt for AI Agents
In website/views/company.py around lines 1563 to 1565, the logger.exception call
redundantly interpolates the exception with {e!s}; remove the formatted
exception from the message and call logger.exception with a descriptive string
(e.g., "Error removing role") so the exception info is recorded automatically;
keep the messages.error line unchanged.
fixes #4624
Screen.Recording.2025-10-14.at.11.mp4
Summary by CodeRabbit