Repository navigation
fix(ui): say why a blocked delete failed instead of printing the error repr - #16566
Conversation
…r repr The user, environment and product attribute delete views put str() of a RestrictedError in their warning, a tuple repr naming every referencing row. They now use the same sentence the API answers a blocked delete with: how many records still refer to the row and which kinds they are. The sentence moves to dojo.utils.restricted_delete_message so both share it, and the environment and product attribute warnings are marked for translation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adversarial review: full tier, OpusTier: full (backend change to Classic UI delete views plus a refactor of the API exception handler's 409 body). Confirmed against the diff: 6 files, no migration, no new endpoint, no permission change. CI read (at 7970a9e): 28 pass, 19 pending (Rest Framework Unit Tests, User Interface Tests, k8s, performance), none red. ruff-linting passed. Regression test: verified. With the three view files taken back to What I drove: the three Classic delete views through the Django test client, against real Break attempts
Findings
Nothing else found. Not findings: the Not checked
RecommendationRequest changes, for R1 only. The fix is correct, the regression test fails without it, and the real-row paths behave. Once R1 is resolved (fixed or answered |
"User cannot be deleted: It cannot be deleted while ..." said the same thing twice. The Classic UI warnings now use restricted_delete_reason, which counts the referencing records and names their kinds without restating that the row cannot be deleted; the API keeps its full sentence. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review resolution
|
Description
When a delete is blocked by records that still refer to the row (a
RestrictedError), three UI delete views putstr()of the error in their warning: deleting a user, an environment, and a product platform, lifecycle or origin.str()of that exception is a Python tuple repr naming every referencing row, so a user referenced by many findings got a very long banner listing all of them:The warning now gives the reason as the API's answer to a blocked delete does: how many records still refer to the row and which kinds they are.
The API's sentence moves out of the exception handler into
dojo.utils.restricted_delete_message, unchanged, anddojo.utils.restricted_delete_reasongives the views the reason alone (their warning already says what cannot be deleted); both share the count and the kinds. One record reads in the singular, and an error that carries no records readsother records still refer to it.The environment and product attribute warnings were f-strings and are now marked for translation; the user warning keeps its existing message id.Test results
New
unittests/test_classic_delete_warning_message.py: a blocked user, environment and product platform delete each shows one warning with the count and kinds, naming no row; one record reads in the singular, and no records still reads. The three view tests failed before the change with the repr.unittests.test_classic_delete_warning_message,test_apiv2_restricted_delete_message,test_product_attributes,test_async_delete,test_apiv2_user,test_apiv2_user_delete_authz,test_apiv2_delete_preview,test_apiv2_export,test_finding_helper,test_sample_data,api_v3.test_apiv3_users,authorization.test_authorizationandtest_rest_framework: 1114 tests, all pass. After the wording change, the delete-message, product attribute and v2 user suites (31 tests) pass again.ruff checkpasses on the changed files.Documentation
None needed: no page documents these warnings.
Checklist
dev.devbranch.🤖 Generated with Claude Code