Skip to content

[BY-3731]: key error handlers in Api.configure() by exported Symbols (breaking) - #54

Open
paulambanks wants to merge 7 commits into
masterfrom
feature/by-3731
Open

paulambanks wants to merge 7 commits into
masterfrom
feature/by-3731

Conversation

@paulambanks

@paulambanks paulambanks commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Breaking change: release as 14.0.0

Handlers in Api.configure() are no longer keyed by name. Import the error type and use it as the key:

// before
Api.configure({ handlers: { accessDenied: fn, default: fn } })

// after
import Api, { AccessDenied } from '@beyonk/http'
Api.configure({ handlers: { [AccessDenied]: fn, default: fn } })

Api.configure() now throws if any handler other than default is keyed by name, so an app that misses the migration fails at startup instead of silently losing its handlers. That's 4 apps in the dashboard repo (dashboard, marketing, admin, checkin), each only using accessDenied. lander only uses default, so it needs no change. Handlers on the request like .notFound(), and default, are unchanged.

Why

Handlers in Api.configure() were matched by class name, which minification renames, so they never fired in production browser builds. A 401 never redirected to login (Sentry DASHBOARD-5W7, DASHBOARD-5WX, MARKETING-APP-F). Each error type now has a fixed identity, exported as a Symbol, so a misspelt name fails the build instead of being silently ignored.

What

  • Exports AccessDenied, PaymentRequired, Forbidden, NotFound, NotAcceptable, Conflict, Gone, PreconditionFailed, ExpectationFailed, BadData and TooManyRequests, made with Symbol.for so they still match if both the ESM and CJS builds get loaded.
  • One status → error type map replaces the 11 error classes and the status-to-class lookup. HttpError sets e.type from it, and both handlers in Api.configure() and on the request are looked up by it. Adding a status is now an export, a map entry and a request method.
  • Only the library's own errors are matched by type, so another library's error with a type field can't hit a handler.
  • A failure that nothing handles is logged once instead of twice.
  • The ErrorHandlers type is keyed by the error types plus default, with the catch-all string key removed.
  • README: docs for handlers in Api.configure(), a table of status / handler on the request / key in Api.configure(), and an "Upgrading to 14" section.

Testing

  • Handler tests grouped under choosing which handler handles a failed request, each describing a general rule (e.g. when configure() has a handler for the status and the request only has a default), one assertion each, plus configure() rejecting name keys and an unhandled failure being logged once.
  • 74 passing, tsc clean. Lint shows only the 4 errors already on master.
  • Broke the code seven ways (checking configure() before the request, ignoring handlers on the request, ignoring default in configure(), not setting e.type, not rejecting name keys, logging twice, accepting name keys at lookup). The first six each fail the suite. The last can't be reached, because configure() rejects name keys first.
  • With Vite 8: a misspelt import fails the build (MISSING_EXPORT), configure() throws on a name key, and a minified build sends a 401 and a 404 to their handlers in configure(), a 500 to default, and lets .notFound() on the request win. TypeScript rejects both a misspelt import and a string key.
  • None of the apps use the removed error classes or constructor.name.

@pkg-pr-new

pkg-pr-new Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@beyonk/http@54

commit: e778310

@paulambanks paulambanks self-assigned this Oct 15, 2026

antony commented Oct 16, 2026

Copy link
Copy Markdown
Member

Are we certain this is the best way to do this?

I can see that us grabbing a constructor name and removing characters is problematic, but wouldn't the way to do this is to put the constructor names in a Symbol enum and then export the Symbols for use by the consumers?

@paulambanks paulambanks changed the title [BY-3731]: fix global error handlers not firing in minified browser builds [BY-3731]: key global error handlers by exported Symbols (breaking) Oct 16, 2026
@paulambanks paulambanks changed the title [BY-3731]: key global error handlers by exported Symbols (breaking) [BY-3731]: key error handlers in Api.configure() by exported Symbols (breaking) Oct 16, 2026
@paulambanks
paulambanks requested a review from antony October 16, 2026 09:42

Copy link
Copy Markdown
Contributor Author

done!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants