import { Request, Response, NextFunction } from "express"; import { GenerateImageResponse } from "../types/api"; /** * Global error handler for the Express application */ export const errorHandler = ( error: Error, req: Request, res: Response, next: NextFunction, ) => { const timestamp = new Date().toISOString(); const requestId = req.requestId || "unknown"; // Log the error console.error(`[${timestamp}] [${requestId}] ERROR:`, { message: error.message, stack: error.stack, path: req.path, method: req.method, body: req.body, query: req.query, }); // Don't send error response if headers already sent if (res.headersSent) { return next(error); } // Determine error type and status code let statusCode = 500; let errorMessage = "Internal server error"; let errorType = "INTERNAL_ERROR"; if (error.name === "ValidationError") { statusCode = 400; errorMessage = error.message; errorType = "VALIDATION_ERROR"; } else if ( error.message.includes("API key") || error.message.includes("authentication") ) { statusCode = 401; errorMessage = "Authentication failed"; errorType = "AUTH_ERROR"; } else if ( error.message.includes("not found") || error.message.includes("404") ) { statusCode = 404; errorMessage = "Resource not found"; errorType = "NOT_FOUND"; } else if ( error.message.includes("timeout") || error.message.includes("503") ) { statusCode = 503; errorMessage = "Service temporarily unavailable"; errorType = "SERVICE_UNAVAILABLE"; } else if ( error.message.includes("overloaded") || error.message.includes("rate limit") ) { statusCode = 429; errorMessage = "Service overloaded, please try again later"; errorType = "RATE_LIMITED"; } // Create error response const errorResponse: GenerateImageResponse = { success: false, message: "Request failed", error: errorMessage, }; // Add additional debug info in development if (process.env["NODE_ENV"] === "development") { (errorResponse as any).debug = { originalError: error.message, errorType, requestId, timestamp, }; } console.log( `[${timestamp}] [${requestId}] Sending error response: ${statusCode} - ${errorMessage}`, ); res.status(statusCode).json(errorResponse); }; /** * 404 handler for unmatched routes */ export const notFoundHandler = (req: Request, res: Response) => { const timestamp = new Date().toISOString(); const requestId = req.requestId || "unknown"; console.log( `[${timestamp}] [${requestId}] 404 - Route not found: ${req.method} ${req.path}`, ); const notFoundResponse: GenerateImageResponse = { success: false, message: "Route not found", error: `The requested endpoint ${req.method} ${req.path} does not exist`, }; res.status(404).json(notFoundResponse); }; /** * Async error wrapper to catch errors in async route handlers */ export const asyncHandler = (fn: Function) => (req: Request, res: Response, next: NextFunction) => { Promise.resolve(fn(req, res, next)).catch(next); };