mirror of
https://github.com/patdelphi/suanming.git
synced 2026-02-28 13:43:11 +08:00
- 完全按照logic/yijing.txt补全所有64卦的完整数据结构 - 包含每卦的卦辞、象传、六爻详解和人生指导 - 重建八字、易经、紫微斗数三个核心分析器 - 实现完整的本地SQLite数据库替代Supabase - 添加本地Express.js后端服务器 - 更新前端API调用为本地接口 - 实现JWT本地认证系统 - 完善历史记录和用户管理功能
93 lines
2.3 KiB
JavaScript
93 lines
2.3 KiB
JavaScript
// 错误处理中间件
|
|
|
|
class AppError extends Error {
|
|
constructor(message, statusCode, code = null) {
|
|
super(message);
|
|
this.statusCode = statusCode;
|
|
this.code = code;
|
|
this.isOperational = true;
|
|
|
|
Error.captureStackTrace(this, this.constructor);
|
|
}
|
|
}
|
|
|
|
// 错误处理中间件
|
|
const errorHandler = (err, req, res, next) => {
|
|
let error = { ...err };
|
|
error.message = err.message;
|
|
|
|
// 记录错误日志
|
|
console.error('错误详情:', {
|
|
message: err.message,
|
|
stack: err.stack,
|
|
url: req.url,
|
|
method: req.method,
|
|
ip: req.ip,
|
|
userAgent: req.get('User-Agent'),
|
|
timestamp: new Date().toISOString()
|
|
});
|
|
|
|
// SQLite错误处理
|
|
if (err.code === 'SQLITE_CONSTRAINT_UNIQUE') {
|
|
const message = '数据已存在,请检查输入';
|
|
error = new AppError(message, 400, 'DUPLICATE_ENTRY');
|
|
}
|
|
|
|
if (err.code === 'SQLITE_CONSTRAINT_FOREIGNKEY') {
|
|
const message = '关联数据不存在';
|
|
error = new AppError(message, 400, 'FOREIGN_KEY_CONSTRAINT');
|
|
}
|
|
|
|
// JWT错误处理
|
|
if (err.name === 'JsonWebTokenError') {
|
|
const message = '无效的访问令牌';
|
|
error = new AppError(message, 401, 'INVALID_TOKEN');
|
|
}
|
|
|
|
if (err.name === 'TokenExpiredError') {
|
|
const message = '访问令牌已过期';
|
|
error = new AppError(message, 401, 'TOKEN_EXPIRED');
|
|
}
|
|
|
|
// 验证错误处理
|
|
if (err.name === 'ValidationError') {
|
|
const message = '输入数据验证失败';
|
|
error = new AppError(message, 400, 'VALIDATION_ERROR');
|
|
}
|
|
|
|
// 默认错误响应
|
|
const statusCode = error.statusCode || 500;
|
|
const errorCode = error.code || 'INTERNAL_ERROR';
|
|
const message = error.isOperational ? error.message : '服务器内部错误';
|
|
|
|
res.status(statusCode).json({
|
|
error: {
|
|
code: errorCode,
|
|
message: message,
|
|
...(process.env.NODE_ENV === 'development' && {
|
|
stack: err.stack,
|
|
details: err
|
|
})
|
|
}
|
|
});
|
|
};
|
|
|
|
// 异步错误捕获包装器
|
|
const asyncHandler = (fn) => {
|
|
return (req, res, next) => {
|
|
Promise.resolve(fn(req, res, next)).catch(next);
|
|
};
|
|
};
|
|
|
|
// 404错误处理
|
|
const notFound = (req, res, next) => {
|
|
const error = new AppError(`请求的资源 ${req.originalUrl} 不存在`, 404, 'NOT_FOUND');
|
|
next(error);
|
|
};
|
|
|
|
module.exports = {
|
|
AppError,
|
|
errorHandler,
|
|
asyncHandler,
|
|
notFound
|
|
}; |