Skip to main content

2026-08-28-web-route-public-exception


title: "A web route no longer answers the caller with the exception text" affects: dartway_serverpod_core_server: "0.12.0"

Who is affected

A project with web routes going through DwWebServerLogger.handleWithExceptions — webhooks, callbacks, anything a foreign system calls.

handleWithExceptions used to catch everything and write e.toString() into the response body. An arbitrary exception carries what it carries: a database error carries its query, a null check carries a file path. All of it was written for us, and whoever called a webhook is not somebody we authenticated. The 500 looked ordinary from the outside, so nothing ever drew attention to what had been sent with it.

Now everything answers with a fixed sentence and 500; the real text goes to the alert and the DwWebServerLog row. Nothing breaks, and the change is silent — which is why this note exists: a caller that was relying on the message is now getting the fixed sentence instead, and nobody on this side will see that happen.

What to change

Go through the routes and find every refusal that was meant for the caller — a missing parameter, a bad signature, an unknown id. Each of those becomes a DwPublicWebException, whose message and status code go out verbatim and which raises no alert, because a route refusing on its own terms is not an incident:

- throw Exception('orderId is required');
+ throw const DwPublicWebException('orderId is required');

- throw Exception('unknown signature');
+ throw const DwPublicWebException('unknown signature', statusCode: 401);

Leave everything else as it is. An unexpected failure answering with a fixed sentence is the point of the change, not a regression.

How to check

Call each route with the input that makes it refuse, and read the response body: a refusal you meant the caller to see says what it always said; anything else says the fixed sentence, and the detail is in the alert and the DwWebServerLog row.

While there: a secret nested inside a list used to reach the log row intact — the sanitiser walked maps and stopped. It is fixed, and no project action is needed, but a log row written before this may still hold one.