feat: add asyncHandler decorator for route error handling
This commit is contained in:
@@ -0,0 +1,33 @@
|
|||||||
|
import { describe, it, expect, vi } from 'vitest'
|
||||||
|
import { asyncHandler } from '../async-handler.js'
|
||||||
|
|
||||||
|
describe('asyncHandler', () => {
|
||||||
|
it('calls the handler and returns result on success', async () => {
|
||||||
|
const handler = vi.fn().mockResolvedValue({ hello: 'world' })
|
||||||
|
const request = {}
|
||||||
|
const reply = { code: vi.fn().mockReturnThis(), send: vi.fn() }
|
||||||
|
const result = await asyncHandler(handler)(request, reply)
|
||||||
|
expect(handler).toHaveBeenCalledWith(request, reply)
|
||||||
|
expect(result).toEqual({ hello: 'world' })
|
||||||
|
})
|
||||||
|
|
||||||
|
it('catches errors and sends 500 with generic message', async () => {
|
||||||
|
const handler = vi.fn().mockRejectedValue(new Error('boom'))
|
||||||
|
const request = { log: { error: vi.fn() } }
|
||||||
|
const reply = { code: vi.fn().mockReturnThis(), send: vi.fn() }
|
||||||
|
await asyncHandler(handler)(request, reply)
|
||||||
|
expect(reply.code).toHaveBeenCalledWith(500)
|
||||||
|
expect(reply.send).toHaveBeenCalledWith({ error: 'Internal server error' })
|
||||||
|
})
|
||||||
|
|
||||||
|
it('uses statusCode from error object when present', async () => {
|
||||||
|
const err = new Error('Not found')
|
||||||
|
err.statusCode = 404
|
||||||
|
const handler = vi.fn().mockRejectedValue(err)
|
||||||
|
const request = { log: { error: vi.fn() } }
|
||||||
|
const reply = { code: vi.fn().mockReturnThis(), send: vi.fn() }
|
||||||
|
await asyncHandler(handler)(request, reply)
|
||||||
|
expect(reply.code).toHaveBeenCalledWith(404)
|
||||||
|
expect(reply.send).toHaveBeenCalledWith({ error: 'Not found' })
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
export function asyncHandler(fn) {
|
||||||
|
return async (request, reply) => {
|
||||||
|
try {
|
||||||
|
return await fn(request, reply)
|
||||||
|
} catch (err) {
|
||||||
|
request.log.error(err)
|
||||||
|
const statusCode = err.statusCode || 500
|
||||||
|
const message = err.statusCode ? err.message : 'Internal server error'
|
||||||
|
return reply.code(statusCode).send({ error: message })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user