quality / commitlint (push) Skipped
quality / changes (push) Failing after 8s
quality / openapi (push) Skipped
quality / web (push) Skipped
quality / api (push) Skipped
CD / quality (push) Failing after 9s
quality / docker-check (push) Skipped
CD / publish (push) Skipped
- genReqId (uuid) + x-request-id в каждом ответе и request_id в error envelope — корреляция ошибок между клиентом и логами - RBAC: /agents/:id/(stats|blocked-ips|blocked-ports) классифицируются как fw:stats:read (reset остаётся под fw:agents:write) - web: test-скрипт + 10 unit-тестов (filter-utils, fleet-kpis, parseClaims, nav) - typecheck-скрипты для api/shared/db; CI: тесты shared и web, typecheck всех пакетов - гигиена: .node-version (22), актуальный .dockerignore, drizzle out → ./migrations, удалены 12 лишних .gitkeep и пустой apps/api/test
56 lines
1.4 KiB
TypeScript
56 lines
1.4 KiB
TypeScript
import type { FastifyInstance } from 'fastify'
|
|
import fp from 'fastify-plugin'
|
|
import { ZodError } from 'zod'
|
|
|
|
export class AppError extends Error {
|
|
constructor(
|
|
public code: string,
|
|
message: string,
|
|
public statusCode = 400,
|
|
) {
|
|
super(message)
|
|
this.name = 'AppError'
|
|
}
|
|
}
|
|
|
|
async function errorHandlerPlugin(app: FastifyInstance) {
|
|
app.setErrorHandler((err, req, reply) => {
|
|
if (err instanceof AppError) {
|
|
return reply.code(err.statusCode).send({
|
|
error: {
|
|
code: err.code,
|
|
message: err.message,
|
|
request_id: String(req.id),
|
|
},
|
|
})
|
|
}
|
|
if (err instanceof ZodError) {
|
|
const message =
|
|
err.issues.map((i) => i.message).join('; ') || 'Validation error'
|
|
return reply.code(400).send({
|
|
error: {
|
|
code: 'VALIDATION_ERROR',
|
|
message,
|
|
request_id: String(req.id),
|
|
},
|
|
})
|
|
}
|
|
const e = err as { statusCode?: number; message?: string }
|
|
const status = e.statusCode ?? 500
|
|
const message =
|
|
status >= 500
|
|
? 'Внутренняя ошибка сервера'
|
|
: e.message || 'Ошибка запроса'
|
|
app.log.error(err)
|
|
return reply.code(status).send({
|
|
error: {
|
|
code: status >= 500 ? 'INTERNAL_ERROR' : 'VALIDATION_ERROR',
|
|
message,
|
|
request_id: String(req.id),
|
|
},
|
|
})
|
|
})
|
|
}
|
|
|
|
export default fp(errorHandlerPlugin, { name: 'error-handler' })
|