45 lines
1.2 KiB
TypeScript
45 lines
1.2 KiB
TypeScript
import { Request, Response, NextFunction } from 'express';
|
|
import { logger } from '../utils/logger';
|
|
|
|
export class AppError extends Error {
|
|
public statusCode: number;
|
|
public isOperational: boolean;
|
|
|
|
constructor(message: string, statusCode: number = 500) {
|
|
super(message);
|
|
this.statusCode = statusCode;
|
|
this.isOperational = true;
|
|
|
|
Error.captureStackTrace(this, this.constructor);
|
|
}
|
|
}
|
|
|
|
export function errorHandler(
|
|
error: AppError,
|
|
req: Request,
|
|
res: Response,
|
|
next: NextFunction
|
|
) {
|
|
const statusCode = error.statusCode || 500;
|
|
const message = error.message || 'Internal Server Error';
|
|
|
|
// Log error
|
|
logger.error('Error occurred:', {
|
|
error: error.message,
|
|
stack: error.stack,
|
|
url: req.url,
|
|
method: req.method,
|
|
ip: (req.headers['x-forwarded-for'] as string) || req.socket.remoteAddress,
|
|
userAgent: req.get('User-Agent')
|
|
});
|
|
|
|
// Don't leak error details in production
|
|
const responseMessage = process.env.NODE_ENV === 'production' && statusCode === 500
|
|
? 'Internal Server Error'
|
|
: message;
|
|
|
|
res.status(statusCode).json({
|
|
error: responseMessage,
|
|
...(process.env.NODE_ENV === 'development' && { stack: error.stack })
|
|
});
|
|
}
|