error.ts31 lines · main
| 1 | import type { Context, ErrorHandler } from 'hono'; |
| 2 | |
| 3 | import { brivenError } from '@briven/shared'; |
| 4 | |
| 5 | import { log } from '../lib/logger.js'; |
| 6 | |
| 7 | /** |
| 8 | * Global error handler. Customer-facing responses carry only `{ code, message }` |
| 9 | * — never stack traces, paths, or internal context. Full error is logged |
| 10 | * server-side keyed by request id. |
| 11 | */ |
| 12 | export const errorHandler: ErrorHandler = (err: Error, c: Context): Response => { |
| 13 | const reqId = c.get('requestId'); |
| 14 | |
| 15 | if (err instanceof brivenError) { |
| 16 | log.warn('handled_error', { |
| 17 | reqId, |
| 18 | code: err.code, |
| 19 | status: err.status, |
| 20 | message: err.message, |
| 21 | }); |
| 22 | return c.json({ code: err.code, message: err.message }, err.status as never); |
| 23 | } |
| 24 | |
| 25 | log.error('unhandled_error', { |
| 26 | reqId, |
| 27 | name: err.name, |
| 28 | message: err.message, |
| 29 | }); |
| 30 | return c.json({ code: 'internal_error', message: 'internal error' }, 500); |
| 31 | }; |