Read RFC 9457 errors for a refused capture, not detail, or the person stops being told which field is wrong #1

Closed
opened 2026-09-21 15:50:07 +00:00 by tiagoagueda · 0 comments
Owner

Postulo's API answers a refusal with an RFC 9457 problem document since
postulo/postulo#296. src/lib/api.js reads the old shape, and one line of it quietly
stops working.

refusalFor at :90-92 does:

return new Error(typeof body.detail === "string" ? body.detail : body.detail.map(problem).join(" "));

The second branch was the useful one: a 422 carried the list of refused fields, each with
its loc and msg, and problem turned them into "title: Field required". detail is
a string in every refusal now, so that branch is dead and the person sees the core's
one-line summary — "Refused: title. See errors for what is wrong with each." — instead
of what is wrong with each.

Nothing breaks. It just says less, which is worse in the place it matters most: somebody
capturing a posting that will not go in, who needs to know which field to correct.

Fix

Read errors, which holds exactly what detail used to:

if (status === 422 && body) {
  const fields = Array.isArray(body.errors) ? body.errors.map(problem).join(" ") : "";
  return new Error(fields || body.detail || "…");
}

Keep the detail fallback: it is what an older Postulo sends, and an extension is updated
on a different day from the instance it talks to.

While there

  • 403 reads body.detail for the scope. That still works, and body.scope now carries
    the scope on its own — worth using rather than showing a sentence built for a developer.
  • 429 throws a generic tooMany. body.retry_after (and the Retry-After header) say
    how long, which is the one thing the person wants to know.
  • The refusals are described in the OpenAPI schema now, with a Problem component.

postulo-firefox builds from this repository's source, so it takes the fix with the next
build.

Postulo's API answers a refusal with an RFC 9457 problem document since postulo/postulo#296. `src/lib/api.js` reads the old shape, and one line of it quietly stops working. `refusalFor` at `:90-92` does: ```js return new Error(typeof body.detail === "string" ? body.detail : body.detail.map(problem).join(" ")); ``` The second branch was the useful one: a 422 carried the list of refused fields, each with its `loc` and `msg`, and `problem` turned them into *"title: Field required"*. `detail` is a string in every refusal now, so that branch is dead and the person sees the core's one-line summary — *"Refused: title. See `errors` for what is wrong with each."* — instead of what is wrong with each. Nothing breaks. It just says less, which is worse in the place it matters most: somebody capturing a posting that will not go in, who needs to know which field to correct. ## Fix Read `errors`, which holds exactly what `detail` used to: ```js if (status === 422 && body) { const fields = Array.isArray(body.errors) ? body.errors.map(problem).join(" ") : ""; return new Error(fields || body.detail || "…"); } ``` Keep the `detail` fallback: it is what an older Postulo sends, and an extension is updated on a different day from the instance it talks to. ## While there - `403` reads `body.detail` for the scope. That still works, and `body.scope` now carries the scope on its own — worth using rather than showing a sentence built for a developer. - `429` throws a generic *tooMany*. `body.retry_after` (and the `Retry-After` header) say how long, which is the one thing the person wants to know. - The refusals are described in the OpenAPI schema now, with a `Problem` component. postulo-firefox builds from this repository's source, so it takes the fix with the next build.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Postulo/postulo-chromium#1
No description provided.