68 lines
1.5 KiB
JavaScript
68 lines
1.5 KiB
JavaScript
/**
|
|
* Custom error class for application errors
|
|
*/
|
|
class AppError extends Error {
|
|
constructor(message, statusCode = 500, isOperational = true) {
|
|
super(message);
|
|
this.statusCode = statusCode;
|
|
this.isOperational = isOperational;
|
|
Error.captureStackTrace(this, this.constructor);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Global error handling middleware
|
|
*/
|
|
function errorHandler(err, req, res, next) {
|
|
let { statusCode = 500, message } = err;
|
|
|
|
// Log error for debugging
|
|
if (process.env.NODE_ENV === 'development') {
|
|
console.error('❌ Error:', err);
|
|
}
|
|
|
|
// Don't leak error details in production for operational errors
|
|
if (process.env.NODE_ENV === 'production' && !err.isOperational) {
|
|
message = 'Something went wrong';
|
|
}
|
|
|
|
// Prepare response
|
|
const response = {
|
|
status: 'error',
|
|
message
|
|
};
|
|
|
|
// Add stack trace in development
|
|
if (process.env.NODE_ENV === 'development') {
|
|
response.stack = err.stack;
|
|
}
|
|
|
|
res.status(statusCode).json(response);
|
|
}
|
|
|
|
/**
|
|
* Handle 404 errors
|
|
*/
|
|
function notFoundHandler(req, res, next) {
|
|
res.status(404).json({
|
|
status: 'error',
|
|
message: 'Route not found'
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Async wrapper to catch errors in async route handlers
|
|
*/
|
|
function asyncHandler(fn) {
|
|
return (req, res, next) => {
|
|
Promise.resolve(fn(req, res, next)).catch(next);
|
|
};
|
|
}
|
|
|
|
module.exports = {
|
|
AppError,
|
|
errorHandler,
|
|
notFoundHandler,
|
|
asyncHandler
|
|
};
|