Skip to content

fix(ui): show toast notification when user deletion returns an error#3205

Merged
crivetimihai merged 6 commits intomainfrom
fix/user-delete-error-toast
Mar 19, 2026
Merged

fix(ui): show toast notification when user deletion returns an error#3205
crivetimihai merged 6 commits intomainfrom
fix/user-delete-error-toast

Conversation

@crivetimihai
Copy link
Member

Note: This PR was re-created from #3021 due to repository maintenance. Your code and branch are intact. @omorros please verify everything looks good.

🔗 Related Issue

Closes #3015


📝 Summary

When deleting a user returns a 4xx error (e.g. self-deletion, last
admin, or DB error), the error HTML was silently discarded by HTMX
because the global htmx:beforeSwap handler does not allow swaps
for user delete responses. The error was never shown to the admin.

This fix attaches hx-on::after-request to the delete button in
both the Jinja template (users_partial.html) and the
Python-generated card (admin.py). On any non-2xx response it
parses the error HTML, extracts the plain text, and calls the
already-existing showErrorMessage() function to display a toast.
No backend changes required.


🏷️ Type of Change

  • Bug fix

🧪 Verification

Check Command Status
Lint suite make lint
Unit tests make test
Coverage ≥ 80% make coverage

✅ Checklist

  • Code formatted (make black isort pre-commit)
  • Tests added/updated for changes
  • Documentation updated (if applicable)
  • No secrets or credentials committed

📓 Notes

Frontend-only fix. The admin_delete_user endpoint already returns
correct 400/403 responses with descriptive messages, this PR only
ensures those messages are surfaced to the user via the existing
toast system.

@crivetimihai crivetimihai added this to the Release 1.0.0-GA milestone Feb 24, 2026
@crivetimihai crivetimihai added bug Something isn't working ui User Interface SHOULD P2: Important but not vital; high-value items that are not crucial for the immediate release labels Feb 24, 2026
@omorros
Copy link
Contributor

omorros commented Feb 24, 2026

Hi @crivetimihai thanks for reopening this! I've verified the code, everything looks good, intact and matching my original changes. Ready for review whenever you get the chance. Thanks!

marekdano
marekdano previously approved these changes Feb 25, 2026
Copy link
Collaborator

@marekdano marekdano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already approved on #3012

LGTM 🚀

@crivetimihai crivetimihai added the merge-queue Rebased and ready to merge label Mar 3, 2026
@marekdano marekdano added the release-fix Critical bugfix required for the release label Mar 11, 2026
@gcgoncalves gcgoncalves force-pushed the fix/user-delete-error-toast branch from dfb03d1 to 2121608 Compare March 16, 2026 16:03
omorros and others added 6 commits March 19, 2026 22:53
Closes #3015

Signed-off-by: Oriol Morros Vilaseca <OM368@student.aru.ac.uk>
Signed-off-by: Oriol Morros Vilaseca <OM368@student.aru.ac.uk>
Signed-off-by: Oriol Morros Vilaseca <OM368@student.aru.ac.uk>
…d-vars

Signed-off-by: Oriol Morros Vilaseca <OM368@student.aru.ac.uk>
Verify that _render_user_card_html includes the hx-on::after-request
attribute with handleDeleteUserError on the delete button.

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
Cover the three key behaviors: extracting text from error HTML,
fallback message when responseText is empty, and no-op on success.

Signed-off-by: Mihai Criveti <crivetimihai@gmail.com>
@crivetimihai
Copy link
Member Author

Review Summary

Rebased onto main (clean, no conflicts) and added test coverage.

Code Review

Correctness: The fix is sound. The global htmx:beforeSwap handler suppresses 4xx responses for elements without data-team-validation="true", which caused user delete errors to be silently swallowed. Adding hx-on::after-request on the delete button correctly intercepts the response after HTMX processes it, and only acts on !event.detail.successful — successful deletions (200 empty response + hx-swap="outerHTML" card removal) are unaffected.

Security: No XSS risk. Triple defense-in-depth:

  1. Server-side: html.escape(str(e)) on exception text
  2. Client-side: d.innerHTML.textContent extraction strips all HTML
  3. showErrorMessage() uses .textContent assignment (not innerHTML)

Consistency: This is the only hx-delete operation in the templates — other entity deletes use RedirectResponse with error query params. The showErrorMessage() toast pattern is already used elsewhere.

Performance: Frontend-only change, no new requests or DOM overhead.

Commits added

  • test(ui): add test for delete button error handler attribute — verifies _render_user_card_html includes hx-on::after-request with handleDeleteUserError
  • test(ui): add JS tests for handleDeleteUserError function — 3 JSDOM tests covering: text extraction from error HTML, empty responseText fallback, and no-op on success

Note

The PR includes some unrelated formatting changes in admin.py (SQL string collapsing, password requirements HTML). These are cosmetic and don't affect behavior.

@crivetimihai crivetimihai merged commit 47ae5e3 into main Mar 19, 2026
45 of 87 checks passed
@crivetimihai crivetimihai deleted the fix/user-delete-error-toast branch March 19, 2026 23:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working merge-queue Rebased and ready to merge release-fix Critical bugfix required for the release SHOULD P2: Important but not vital; high-value items that are not crucial for the immediate release ui User Interface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG][UI]: No toast notification is displayed when deleting users returns an error message

3 participants