Rename directory from email-server-worker to email-worker for clarity and brevity. Update all references in CLAUDE.md documentation.
81 lines
2.9 KiB
TypeScript
81 lines
2.9 KiB
TypeScript
import { ErrorRequestHandler, Request, Response } from "express";
|
|
import createHttpError, { HttpError } from "http-errors";
|
|
import { createLogger } from '../lib/logger';
|
|
import { NgitLocals } from "../types/NgitLocals";
|
|
import { failedRequestCounter } from "../lib/metricsCounters";
|
|
import { SupportedRoutes } from "../types/enums/SupportedRoutes";
|
|
|
|
const consoleLog = createLogger("server:server");
|
|
|
|
/**
|
|
* Router koji se zadnji poziva, a koji sastavlja odgovor u slučaju greške
|
|
* @param err
|
|
* @param req
|
|
* @param res
|
|
* @param next
|
|
*/
|
|
export const errorRouter:ErrorRequestHandler = async (err:HttpError, req, res, next) => {
|
|
|
|
const requestPath = req.path as SupportedRoutes;
|
|
|
|
// kako je ovaj error handler dosta složen, moguće je da negdje baci grešku
|
|
// > zato je zamotan u try-catch
|
|
// > na taj način osiguravam da neće srušiti cijeli proces
|
|
try {
|
|
|
|
let { name:errorLogName, message:errorLogText } = err;
|
|
let responseBody:string = "";
|
|
|
|
switch(err.status) {
|
|
case 400:
|
|
responseBody = 'bad request';
|
|
break;
|
|
case 401:
|
|
responseBody = 'unauthorized';
|
|
break;
|
|
case 403:
|
|
responseBody = 'forbidden';
|
|
break;
|
|
case 404:
|
|
consoleLog(`page not found ${req.method} ${requestPath}`)
|
|
responseBody = 'page not found';
|
|
errorLogText = `page ${requestPath} not found`;
|
|
break;
|
|
case 500:
|
|
responseBody = "internal server error";
|
|
errorLogText = err.message;
|
|
break;
|
|
default:
|
|
responseBody = err.name;
|
|
errorLogText = `err.status=${err.status};err.name=${err.name};err.message=${err.message}`;
|
|
}
|
|
|
|
consoleLog(`${errorLogName}:${errorLogText}`);
|
|
|
|
// `headersSent` će biti TRUE ako je router kod kojeg se dogodila greška već poslao header-e
|
|
// > ako ih probam ponovo postaviti, to će baciti grešku ... a to ovdje mogu izbjeći
|
|
if(!res.headersSent) {
|
|
res.status(err.status);
|
|
res.setHeader('Content-Type', "text/html");
|
|
res.end(responseBody);
|
|
} else {
|
|
// AKO nije pozvan `end` - pozovi ga i završi obradu zahtjeva
|
|
// ... u suprotnom će konekcija ostati otvorena do timeout-a
|
|
if(!res.writableEnded) {
|
|
res.end();
|
|
}
|
|
}
|
|
|
|
} catch(ex:any) {
|
|
// ovu grešku će obraditi `finalErrorRouter`
|
|
next(createHttpError(500, ex));
|
|
}
|
|
|
|
// ne mogu dopustiti da prometheus client sruši server
|
|
try {
|
|
failedRequestCounter.inc({ path: requestPath, status: err.status });
|
|
(res.locals as NgitLocals).stopPrometheusTimer({ path: req.path, status: err.status });
|
|
} catch(ex:any) {
|
|
console.error(ex);
|
|
}
|
|
}; |