- Shipped
- September 16, 2026 at 5:38 PM UTC
- Author
- Kamo
- Commit
- 7e58d55
2a72597 gave the campaign controllers the member's sentence instead of "Bad Request". The same loss happened everywhere else in EmailService that refuses with a ResponseStatusException: - Contacts: ContactRestController refuses with "VIEW_CONTACTS required", "No organization in session", "The organization's default book cannot be deleted"…, and the contacts screen showed "Forbidden" / "Conflict". - Aliases, shared mailboxes and mailboxes: KamoMailDomainValidator refuses an address outside the organization's verified domain with a sentence naming the domain. The three create endpoints caught it as a generic Exception and answered 500 with the exception's own text ("403 FORBIDDEN \"Email address must…\""). CampaignErrorAdvice becomes StatusReasonAdvice and applies to every controller. It still shows only a ResponseStatusException's reason, text written to be read; every other exception keeps Boot's default body (server.error.include-message stays never). The body carries the sentence as both error and message, since the contacts client reads message first and the mailbox and campaign clients read error. The three create endpoints now let a ResponseStatusException through their catch-all, so it reaches the advice with its own status. StatusReasonAdviceTest runs the real controllers on an embedded server through Boot's error handling: a campaign refusal, a contacts right, and an alias on the wrong domain (403 with the domain, where it was a 500). 1561 tests: only TransactionalSendRatchetTest fails, as it does on main.