diff --git a/server/src/lib/__tests__/async-handler.test.js b/server/src/lib/__tests__/async-handler.test.js new file mode 100644 index 0000000..710d56b --- /dev/null +++ b/server/src/lib/__tests__/async-handler.test.js @@ -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' }) + }) +}) diff --git a/server/src/lib/async-handler.js b/server/src/lib/async-handler.js new file mode 100644 index 0000000..6924971 --- /dev/null +++ b/server/src/lib/async-handler.js @@ -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 }) + } + } +}