Global app.onError handler already in app.ts catches all unhandled route exceptions. Production mode returns "Internal server error" only. Tests verify no stack traces or file paths leak in responses. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
53 lines
1.8 KiB
TypeScript
53 lines
1.8 KiB
TypeScript
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
|
|
import { Hono } from 'hono'
|
|
|
|
describe('global error handler', () => {
|
|
it('returns 500 with sanitized error in production mode', async () => {
|
|
const originalEnv = process.env.NODE_ENV
|
|
process.env.NODE_ENV = 'production'
|
|
|
|
const app = new Hono()
|
|
app.onError((_err, c) => {
|
|
const msg = process.env.NODE_ENV === 'production' ? 'Internal server error' : _err.message
|
|
return c.json({ error: msg }, 500)
|
|
})
|
|
app.get('/test', () => { throw new Error('DB connection failed at /path/to/file.ts:42') })
|
|
|
|
const res = await app.request('/test')
|
|
expect(res.status).toBe(500)
|
|
const body = await res.json() as { error: string }
|
|
expect(body.error).toBe('Internal server error')
|
|
// Must NOT contain stack trace or file paths
|
|
expect(body.error).not.toContain('.ts')
|
|
expect(body.error).not.toContain('Error')
|
|
expect(body.error).not.toContain('DB connection')
|
|
|
|
process.env.NODE_ENV = originalEnv
|
|
})
|
|
|
|
it('returns error message in development mode', async () => {
|
|
const app = new Hono()
|
|
app.onError((_err, c) => {
|
|
const msg = process.env.NODE_ENV === 'production' ? 'Internal server error' : _err.message
|
|
return c.json({ error: msg }, 500)
|
|
})
|
|
app.get('/test', () => { throw new Error('Something broke') })
|
|
|
|
const res = await app.request('/test')
|
|
expect(res.status).toBe(500)
|
|
const body = await res.json() as { error: string }
|
|
expect(body.error).toBe('Something broke')
|
|
})
|
|
|
|
it('async route handler errors are caught', async () => {
|
|
const app = new Hono()
|
|
app.onError((_err, c) => c.json({ error: 'Internal server error' }, 500))
|
|
app.get('/test', async () => {
|
|
throw new Error('async failure')
|
|
})
|
|
|
|
const res = await app.request('/test')
|
|
expect(res.status).toBe(500)
|
|
})
|
|
})
|