44 lines
1.3 KiB
TypeScript
44 lines
1.3 KiB
TypeScript
import { DatabaseError } from 'pg-protocol'
|
|
import StatusError from '../lib/status_error.ts'
|
|
import { type ErrorHandler } from '../types.ts'
|
|
|
|
const databaseErrorCodes: Record<string, number> = {
|
|
23505: 409,
|
|
23514: 409,
|
|
}
|
|
|
|
const defaultHandler: ErrorHandler = (error, _request, reply) => {
|
|
return reply
|
|
.type('text/html')
|
|
.send(
|
|
`<h1>Error</h1><pre>${JSON.stringify(error, ['name', ...Object.getOwnPropertyNames(error)], 2).replaceAll('\\n', '\n')}</pre>`,
|
|
)
|
|
}
|
|
|
|
export default function createErrorHandler(handler: ErrorHandler = defaultHandler): ErrorHandler {
|
|
return async function errorHandler(error, request, reply) {
|
|
if (error instanceof DatabaseError && error.code && error.code in databaseErrorCodes) {
|
|
error = new StatusError(databaseErrorCodes[error.code], error.detail || 'Database Error', { cause: error })
|
|
}
|
|
|
|
reply.log.error({ req: request, err: error }, error?.message)
|
|
|
|
// @ts-ignore
|
|
reply.status(error.status || error.statusCode || 500)
|
|
|
|
if (request.headers.accept?.includes('application/json')) {
|
|
return reply.send(
|
|
// @ts-ignore
|
|
error.toJSON?.() || {
|
|
name: error.name,
|
|
message: error.message,
|
|
// @ts-ignore
|
|
status: error.status || error.statusCode || 500,
|
|
},
|
|
)
|
|
}
|
|
|
|
return handler(error, request, reply)
|
|
}
|
|
}
|