A transient database fault must not 500 the request

FixSecurityService
Shipped
August 28, 2026 at 8:29 PM UTC
Author
Kamo
Commit
e88dce8

The lead Communications tab reported "We couldn't load this lead's communications" for org 1168485648209608710 on 2026-08-28. The endpoint returned 500 five times between 20:02 and 20:03, and the body was Spring's default error JSON rather than LeadCommunicationsController's own — proof the controller never ran. **************** reads child_org_security_models to answer "does this org have CRM" on every /api/security/leads/** request. Yugabyte raised a retryable 40001 on that table ("schema version mismatch for table ...fad1: expected 6, got 3") while a catalog change propagated, the CannotAcquireLockException escaped preHandle, and the whole request became a 500 before any handler existed to report it. Every other reader of those rows already survives such a burst — OrganizationController and MemberRightsAppliedService log and carry on — so the gates were the last place a blip could still fail a request outright. EntitlementGateReads now runs both gates' reads: three attempts with a short backoff, which turns nearly every burst back into a real answer, and then falls open rather than closed. An unanswerable read means "not known right now", and neither alternative says that — a 403 would tell the member their organization has not bought an app it has bought, and a 500 says the feature is broken. Falling open hands the decision to the handler's own authorisation, which is separate and stricter: LeadCommunicationsController still requires a valid org session, the lead to be in that org, and VIEW_UNASSIGNED_LEADS / VIEW_LEAD_CONTACT_INFO_OTHERS; PatientCommsController still requires VIEW_CHART. What is briefly skipped is the billing question, not the access one. Non-transient faults still propagate, so a genuine break in enforcement stays loud rather than silently disabling the gate. **************** carried the identical defect on the same request path family and gets the same treatment.

All changes

Like what you see shipping?

Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.

Start Free ForeverView Pricing