Commit 683f190
authored
feat(node): Auto-register Koa error handler on app start (#23463)
The Koa error handler is now registered automatically when the app
starts, so `setupKoaErrorHandler` no longer needs to be called. This
mirrors the Hapi change and removes the last manual setup step for Koa
error capture.
### How it works
Koa's `Application` is an `EventEmitter` and emits `'error'` for every
request error that bubbles up unhandled — the same set of errors a
top-level try/catch middleware would see, but **order-independent**. So
instead of injecting a `try/catch` middleware (whose position in the
onion stack was load-bearing), we attach a single `app.on('error')`
listener.
Auto-registration rides a new orchestrion channel on
`Application.prototype.callback`. `app.listen()` always funnels through
`callback()`, so this also covers `http.createServer(app.callback())`.
### Decisions
- **Attach on the channel's `end`, not `start`.** Koa registers its own
default `error` listener inside `callback()` — but only if none exist
yet (`if (!this.listenerCount('error')) this.on('error',
this.onerror)`). Attaching before that runs would suppress koa's
built-in error logging. Acting on `end` (after the method body) means
koa's default listener is already in place and ours is added alongside
it.
- **`app.on('error')` over a first-position `try/catch` middleware.**
Event listeners are additive and order-independent, so there is no
ordering conflict with a user's own error handling: if a user middleware
catches and handles an error, koa never emits and we correctly don't
capture; if it's unhandled, our listener and any user `app.on('error')`
both run.
- **`setupKoaErrorHandler` stays as an idempotent delegate**
(deprecated) rather than a hard no-op, so a direct call still works
without orchestrion (e.g. error capture with tracing disabled). An
idempotency marker on the app means auto-registration plus a manual call
never stack up duplicate listeners.
- **`attachKoaErrorHandler` is also deprecated** and marked internal —
it exists only so the deprecated `setupKoaErrorHandler` can delegate to
it, and should not be called directly.
- The Koa integration files were collocated into a `koa/` folder to
match the Hapi layout.
Auto-registration is exercised end-to-end by dropping the manual call
from the koa integration-test scenario and the e2e app; a new unit suite
covers the attach behaviour (single idempotent listener, guards, and
capture mechanism).
A follow-up will do the same for Express.1 parent a28b354 commit 683f190
20 files changed
Lines changed: 185 additions & 69 deletions
File tree
- dev-packages
- e2e-tests/test-applications/node-koa
- tests
- node-integration-tests/suites/tracing/koa
- packages
- astro/src
- aws-serverless/src
- bun/src
- elysia/src
- google-cloud-serverless/src
- node/src
- integrations/tracing
- koa
- remix/src/server
- server-utils/src
- integrations/koa
- orchestrion/config
- solidstart/src/server
- sveltekit/src/server
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
287 | 287 | | |
288 | 288 | | |
289 | 289 | | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
290 | 296 | | |
291 | 297 | | |
292 | 298 | | |
| |||
Lines changed: 0 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
25 | | - | |
26 | | - | |
27 | 25 | | |
28 | 26 | | |
29 | 27 | | |
| |||
Lines changed: 3 additions & 19 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
66 | 66 | | |
67 | 67 | | |
68 | 68 | | |
69 | | - | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
70 | 72 | | |
71 | 73 | | |
72 | 74 | | |
| |||
85 | 87 | | |
86 | 88 | | |
87 | 89 | | |
88 | | - | |
89 | | - | |
90 | | - | |
91 | | - | |
92 | | - | |
93 | | - | |
94 | | - | |
95 | | - | |
96 | | - | |
97 | | - | |
98 | | - | |
99 | | - | |
100 | | - | |
101 | | - | |
102 | | - | |
103 | | - | |
104 | | - | |
105 | | - | |
106 | 90 | | |
107 | 91 | | |
108 | 92 | | |
| |||
Lines changed: 2 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | | - | |
3 | 2 | | |
4 | 3 | | |
5 | 4 | | |
6 | 5 | | |
7 | 6 | | |
8 | 7 | | |
9 | 8 | | |
10 | | - | |
11 | | - | |
| 9 | + | |
| 10 | + | |
12 | 11 | | |
13 | 12 | | |
14 | 13 | | |
| |||
Lines changed: 10 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
12 | 22 | | |
13 | 23 | | |
14 | 24 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
126 | 126 | | |
127 | 127 | | |
128 | 128 | | |
| 129 | + | |
129 | 130 | | |
130 | 131 | | |
131 | 132 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
96 | 96 | | |
97 | 97 | | |
98 | 98 | | |
| 99 | + | |
99 | 100 | | |
100 | 101 | | |
101 | 102 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
120 | 120 | | |
121 | 121 | | |
122 | 122 | | |
| 123 | + | |
123 | 124 | | |
124 | 125 | | |
125 | 126 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
99 | 99 | | |
100 | 100 | | |
101 | 101 | | |
| 102 | + | |
102 | 103 | | |
103 | 104 | | |
104 | 105 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
97 | 97 | | |
98 | 98 | | |
99 | 99 | | |
| 100 | + | |
100 | 101 | | |
101 | 102 | | |
102 | 103 | | |
| |||
0 commit comments