Skip to content

Commit d1eee9c

Browse files
committed
🔧 fix: #1348 onAfterResponse runs twice if NotFoundError thrown and onError provided
1 parent 4d6f5dd commit d1eee9c

File tree

5 files changed

+59
-14
lines changed

5 files changed

+59
-14
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# 1.3.12 - 19 Aug 2025
2+
Bug fix:
3+
- [#1348](https://github.com/elysiajs/elysia/issues/1348) onAfterResponse runs twice if NotFoundError thrown and onError provided
4+
15
# 1.3.11 - 18 Aug 2025
26
Bug fix:
37
- [#1346](https://github.com/elysiajs/elysia/issues/1346) cannot declare 'mep' twice

example/a.ts

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,26 @@
11
import { Elysia, t } from '../src'
2+
import { req } from '../test/utils'
23

3-
const IdsModel = new Elysia().model({
4-
ids: t.Object({
5-
ids: t.Array(t.String())
6-
})
7-
})
4+
let isAfterResponseCalled = false
85

9-
const app = new Elysia({ aot: false })
10-
.use(IdsModel)
11-
.get('/', ({ query }) => query, {
12-
query: 'ids'
6+
const app = new Elysia({ precompile: true })
7+
.onAfterResponse(() => {
8+
isAfterResponseCalled = true
9+
})
10+
.onError(() => {
11+
return new Response('a', {
12+
status: 401,
13+
headers: {
14+
awd: 'b'
15+
}
16+
})
1317
})
14-
.listen(3000)
18+
.compile()
19+
20+
// console.log(app.handleError.toString())
21+
22+
await app.handle(req('/'))
23+
// wait for next tick
24+
await Bun.sleep(1)
25+
26+
console.log(isAfterResponseCalled)

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "elysia",
33
"description": "Ergonomic Framework for Human",
4-
"version": "1.3.11",
4+
"version": "1.3.12",
55
"author": {
66
"name": "saltyAom",
77
"url": "https://github.com/SaltyAom",

src/compose.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2264,7 +2264,7 @@ export const composeGeneralHandler = (app: AnyElysia) => {
22642264
findDynamicRoute += router.http.root.ALL ? '??router.find("ALL",p)\n' : '\n'
22652265

22662266
let afterResponse = `c.error=notFound\n`
2267-
if (app.event.afterResponse?.length) {
2267+
if (app.event.afterResponse?.length && !app.event.error) {
22682268
const prefix = app.event.afterResponse.some(isAsync) ? 'async' : ''
22692269
afterResponse += `\nsetImmediate(${prefix}()=>{`
22702270

@@ -2532,7 +2532,9 @@ export const composeErrorHandler = (app: AnyElysia) => {
25322532
if (hasReturn(handler)) {
25332533
fnLiteral +=
25342534
`_r=${response}\nif(_r!==undefined){` +
2535-
`if(_r instanceof Response)return mapResponse(_r,set${adapter.mapResponseContext})\n` +
2535+
`if(_r instanceof Response){` +
2536+
afterResponse() +
2537+
`return mapResponse(_r,set${adapter.mapResponseContext})}` +
25362538
`if(_r instanceof ElysiaCustomStatusResponse){` +
25372539
`error.status=error.code\n` +
25382540
`error.message = error.response` +
@@ -2562,7 +2564,9 @@ export const composeErrorHandler = (app: AnyElysia) => {
25622564

25632565
mapResponseReporter.resolve()
25642566

2565-
fnLiteral += `return mapResponse(${saveResponse}_r,set${adapter.mapResponseContext})}`
2567+
fnLiteral +=
2568+
afterResponse() +
2569+
`return mapResponse(${saveResponse}_r,set${adapter.mapResponseContext})}`
25662570
} else fnLiteral += response
25672571

25682572
fnLiteral += '}'

test/lifecycle/response.test.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,4 +207,29 @@ describe('On After Response Error', () => {
207207
expect(isOnResponseCalled).toBeTrue()
208208
expect(onResponseCalledCounter).toBe(1)
209209
})
210+
211+
it.each([
212+
{ aot: true, withOnError: true },
213+
{ aot: true, withOnError: false },
214+
215+
{ aot: false, withOnError: true },
216+
{ aot: false, withOnError: false }
217+
])(
218+
'should execute onAfterResponse once during NotFoundError aot=$aot,\twithOnError=$withOnError',
219+
async ({ aot, withOnError }) => {
220+
let counter = 0
221+
222+
const app = new Elysia({ aot }).onAfterResponse(() => {
223+
counter++
224+
})
225+
226+
if (withOnError) app.onError(() => {})
227+
228+
const req = new Request('http://localhost/notFound')
229+
await app.handle(req)
230+
await Bun.sleep(1)
231+
232+
expect(counter).toBe(1)
233+
}
234+
)
210235
})

0 commit comments

Comments
 (0)