Files
router-lists-ui/backend/middleware/errorHandler.js
T

82 lines
2.3 KiB
JavaScript

/**
* Централизованный обработчик ошибок
*/
const promClient = require('prom-client');
// Метрики
const http304 = new promClient.Counter({ name: 'http_304_total', help: 'HTTP 304 responses' });
const http412 = new promClient.Counter({ name: 'http_412_total', help: 'HTTP 412 responses' });
const http423 = new promClient.Counter({ name: 'http_423_total', help: 'HTTP 423 responses' });
/**
* Отправить успешный ответ с метаданными
*/
function sendOk(res, meta) {
if (meta?.etag) res.set('ETag', String(meta.etag));
if (meta?.lastModified) res.set('Last-Modified', new Date(meta.lastModified).toUTCString());
if (typeof meta?.contentLength === 'number') res.set('Content-Length-Source', String(meta.contentLength));
return res.json({
ok: true,
etag: meta?.etag || null,
lastModified: meta?.lastModified || null,
contentLength: meta?.contentLength ?? null
});
}
/**
* Отправить ошибку
*/
function sendError(res, status, message, code, details) {
const requestId = res.req?.id;
try {
if (status === 304) http304.inc();
if (status === 412) http412.inc();
if (status === 423) http423.inc();
} catch {}
return res.status(status).json({ code, message, details, requestId });
}
/**
* Проверить If-None-Match заголовок
*/
function checkIfNoneMatch(req, res, etag) {
const inm = req.headers && (req.headers['if-none-match'] || req.headers['If-None-Match']);
if (inm && etag && String(inm) === String(etag)) {
try { http304.inc(); } catch {}
res.status(304).end();
return true;
}
return false;
}
/**
* Централизованный error handler middleware
*/
function errorHandler(err, req, res, next) {
const status = typeof err?.status === 'number' ? err.status : 500;
const code = err?.code || 'E_INTERNAL';
const message = status === 500 && process.env.NODE_ENV === 'production'
? 'Internal Server Error'
: (err?.message || 'Error');
const details = err?.details;
const requestId = req?.id;
try {
req.log?.error({ err, code, requestId }, 'request error');
} catch {}
res.status(status).json({ code, message, details, requestId });
}
module.exports = {
sendOk,
sendError,
checkIfNoneMatch,
errorHandler,
http304,
http412,
http423,
};