CoolFace
Apppublic

sanket3280/code-execution

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
errorHandler.js150 linesDownload Raw Back to utils
1/**2 * Centralized Error Handling3 * Provides consistent error responses and logging4 */5 6const logger = require('./logger');7const { config } = require('../config/env.config');8 9/**10 * Custom Application Error11 */12class AppError extends Error {13  constructor(message, statusCode = 500, isOperational = true) {14    super(message);15    this.statusCode = statusCode;16    this.isOperational = isOperational;17    this.status = `${statusCode}`.startsWith('4') ? 'fail' : 'error';18    19    Error.captureStackTrace(this, this.constructor);20  }21}22 23/**24 * Async handler wrapper to catch errors in async route handlers25 */26const asyncHandler = (fn) => {27  return (req, res, next) => {28    Promise.resolve(fn(req, res, next)).catch(next);29  };30};31 32/**33 * Handle validation errors34 */35const handleValidationError = (err) => {36  const errors = Object.values(err.errors).map(el => el.message);37  const message = `Invalid input data. ${errors.join('. ')}`;38  return new AppError(message, 400);39};40 41/**42 * Handle duplicate key errors43 */44const handleDuplicateKeyError = (err) => {45  const field = Object.keys(err.keyValue)[0];46  const value = err.keyValue[field];47  const message = `${field} '${value}' already exists. Please use another value.`;48  return new AppError(message, 400);49};50 51/**52 * Handle JWT errors53 */54const handleJWTError = () => {55  return new AppError('Invalid token. Please log in again.', 401);56};57 58/**59 * Handle JWT expired error60 */61const handleJWTExpiredError = () => {62  return new AppError('Your token has expired. Please log in again.', 401);63};64 65/**66 * Handle cast errors (invalid MongoDB ObjectId)67 */68const handleCastError = (err) => {69  const message = `Invalid ${err.path}: ${err.value}`;70  return new AppError(message, 400);71};72 73/**74 * Send error response in development75 */76const sendErrorDev = (err, res) => {77  res.status(err.statusCode).json({78    status: err.status,79    error: err,80    message: err.message,81    stack: err.stack,82  });83};84 85/**86 * Send error response in production87 */88const sendErrorProd = (err, res) => {89  // Operational, trusted error: send message to client90  if (err.isOperational) {91    res.status(err.statusCode).json({92      status: err.status,93      message: err.message,94    });95  } 96  // Programming or unknown error: don't leak error details97  else {98    logger.error('Unexpected error', err);99    res.status(500).json({100      status: 'error',101      message: 'Something went wrong',102    });103  }104};105 106/**107 * Global error handling middleware108 */109const errorHandler = (err, req, res, next) => {110  err.statusCode = err.statusCode || 500;111  err.status = err.status || 'error';112 113  // Log error114  logger.error(`Error in ${req.method} ${req.path}`, err, {115    statusCode: err.statusCode,116    userId: req.user?.id,117  });118 119  if (config.isDevelopment) {120    sendErrorDev(err, res);121  } else {122    let error = { ...err };123    error.message = err.message;124 125    // Handle specific error types126    if (err.name === 'ValidationError') error = handleValidationError(err);127    if (err.code === 11000) error = handleDuplicateKeyError(err);128    if (err.name === 'JsonWebTokenError') error = handleJWTError();129    if (err.name === 'TokenExpiredError') error = handleJWTExpiredError();130    if (err.name === 'CastError') error = handleCastError(err);131 132    sendErrorProd(error, res);133  }134};135 136/**137 * Handle 404 errors138 */139const notFound = (req, res, next) => {140  const error = new AppError(`Route ${req.originalUrl} not found`, 404);141  next(error);142};143 144module.exports = {145  AppError,146  asyncHandler,147  errorHandler,148  notFound,149};150