Newer
Older
express-blog / src / middleware / errorHandler.js
@Jason Jason on 18 Jul 1 KB modified: content
// src/middleware/errorHandler
const crypto = require("crypto");
const getBaseContext = require("../utils/baseContext");
const { getErrorContext } = require("../utils/errorContext");
const { buildErrorRenderContext } = require("../utils/buildErrorRenderContext");
const { isDev } = require("../utils/env");
const {
  DEFAULT_ERROR_MESSAGE,
  DEFAULT_STACK_TRACE,
  DEFAULT_STATUS_CODE,
  DEFAULT_LOG_LEVEL,
  ERROR_REDIRECT_PATH,
} = require("../constants/errorConstants");

module.exports = async (err, req, res, next) => {
  const statusCode = err.statusCode ?? DEFAULT_STATUS_CODE;
  const message = err.message ?? DEFAULT_ERROR_MESSAGE;
  const stack = err.stack ?? DEFAULT_STACK_TRACE;
  const code = err.code ?? null;
  const requestId = crypto.randomUUID?.() ?? Date.now().toString(36);
  const timestamp = new Date().toISOString();

  const logEntry = {
    timestamp,
    level: DEFAULT_LOG_LEVEL,
    requestId,
    method: req.method,
    url: req.originalUrl || req.url,
    statusCode,
    code,
    message,
    stack,
    headers: req.headers,
    query: req.query,
    body: req.body,
    ip: req.ip || req.connection?.remoteAddress,
  };

  if (req?.log?.error) {
    req.log.error(logEntry); // fixme, logs arent logging?
    console.log(logEntry);
  } else {
    console.error(logEntry);
  }

  const errorContext = getErrorContext(code || statusCode);

  if (!isDev && !req?.isAuthenticated) {
    res.customRedirect(
      `${ERROR_REDIRECT_PATH}?code=${errorContext.statusCode}`
    );
    return;
  }

  const context = buildErrorRenderContext({
    req,
    requestId,
    timestamp,
    code,
    statusCode,
    message,
    stack,
    errorContext,
  });

  const errorPageContext = await getBaseContext(req?.isAuthenticated, context);
  res.status(errorContext.statusCode);
  res.renderGenericMessage(errorPageContext);
};