63 lines
1.3 KiB
JavaScript
63 lines
1.3 KiB
JavaScript
class AppError extends Error {
|
|
constructor(message, statusCode = 500, code = 'INTERNAL_ERROR') {
|
|
super(message);
|
|
this.statusCode = statusCode;
|
|
this.code = code;
|
|
this.isOperational = true;
|
|
Error.captureStackTrace(this, this.constructor);
|
|
}
|
|
}
|
|
|
|
function errorHandler(err, req, res, next) {
|
|
console.error({
|
|
message: err.message,
|
|
stack: err.stack,
|
|
url: req.url,
|
|
method: req.method,
|
|
userId: req.userId,
|
|
});
|
|
|
|
if (err instanceof AppError && err.isOperational) {
|
|
return res.status(err.statusCode).json({
|
|
error: err.message,
|
|
code: err.code,
|
|
});
|
|
}
|
|
|
|
// 数据库唯一性冲突
|
|
if (err.code === 'SQLITE_CONSTRAINT_UNIQUE') {
|
|
return res.status(400).json({
|
|
error: '数据已存在',
|
|
code: 'DUPLICATE_ENTRY',
|
|
});
|
|
}
|
|
|
|
// 其他数据库错误
|
|
if (err.code && err.code.startsWith('SQLITE_')) {
|
|
return res.status(500).json({
|
|
error: '数据库错误',
|
|
code: 'DATABASE_ERROR',
|
|
});
|
|
}
|
|
|
|
// 默认错误响应
|
|
res.status(500).json({
|
|
error: process.env.NODE_ENV === 'production'
|
|
? '服务器内部错误'
|
|
: err.message,
|
|
code: 'INTERNAL_ERROR',
|
|
});
|
|
}
|
|
|
|
function asyncHandler(fn) {
|
|
return (req, res, next) => {
|
|
Promise.resolve(fn(req, res, next)).catch(next);
|
|
};
|
|
}
|
|
|
|
module.exports = {
|
|
AppError,
|
|
errorHandler,
|
|
asyncHandler,
|
|
};
|