errorHandler.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.catchAsync = exports.notFound = exports.errorHandler = exports.AppError = void 0;
  4. const loggerService_1 = require("../services/loggerService");
  5. class AppError extends Error {
  6. constructor(message, statusCode) {
  7. super(message);
  8. this.statusCode = statusCode;
  9. this.isOperational = true;
  10. Error.captureStackTrace(this, this.constructor);
  11. }
  12. }
  13. exports.AppError = AppError;
  14. const sendErrorDev = (err, res) => {
  15. res.status(err.statusCode).json({
  16. status: 'error',
  17. error: err,
  18. message: err.message,
  19. stack: err.stack
  20. });
  21. };
  22. const sendErrorProd = (err, res) => {
  23. if (err.isOperational) {
  24. res.status(err.statusCode).json({
  25. status: 'error',
  26. message: err.message
  27. });
  28. }
  29. else {
  30. console.error('ERROR 💥', err);
  31. res.status(500).json({
  32. status: 'error',
  33. message: '服务器内部错误'
  34. });
  35. }
  36. };
  37. const handleDBError = (err) => {
  38. if (err.code === 'ER_NO_SUCH_TABLE') {
  39. return new AppError('数据表不存在,请检查数据库设置', 500);
  40. }
  41. if (err.code === 'ER_ACCESS_DENIED_ERROR') {
  42. return new AppError('数据库访问被拒绝,请检查权限设置', 500);
  43. }
  44. if (err.code === 'ECONNREFUSED') {
  45. return new AppError('无法连接到数据库,请检查数据库服务器状态', 500);
  46. }
  47. if (err.code === 'ER_BAD_FIELD_ERROR') {
  48. return new AppError('数据库字段错误', 400);
  49. }
  50. return new AppError('数据库操作失败', 500);
  51. };
  52. const errorHandler = (err, req, res, next) => {
  53. err.statusCode = err.statusCode || 500;
  54. err.status = err.status || 'error';
  55. loggerService_1.LoggerService.error('发生错误', {
  56. source: 'error_handler',
  57. module: 'global',
  58. details: JSON.stringify({
  59. statusCode: err.statusCode,
  60. message: err.message,
  61. path: req.path,
  62. method: req.method,
  63. ip: req.ip,
  64. userAgent: req.get('user-agent')
  65. })
  66. }).catch(logErr => {
  67. console.error('错误日志写入失败:', logErr);
  68. });
  69. if (err.code && typeof err.code === 'string' && err.code.startsWith('ER_')) {
  70. err = handleDBError(err);
  71. }
  72. if (process.env.NODE_ENV === 'development') {
  73. sendErrorDev(err, res);
  74. }
  75. else {
  76. sendErrorProd(err, res);
  77. }
  78. };
  79. exports.errorHandler = errorHandler;
  80. const notFound = (req, res, next) => {
  81. const err = new AppError(`找不到路由 ${req.originalUrl}`, 404);
  82. loggerService_1.LoggerService.warn('未找到路由', {
  83. source: 'error_handler',
  84. module: 'not_found',
  85. details: JSON.stringify({
  86. path: req.originalUrl,
  87. method: req.method,
  88. ip: req.ip
  89. })
  90. }).catch(logErr => {
  91. console.error('404错误日志写入失败:', logErr);
  92. });
  93. next(err);
  94. };
  95. exports.notFound = notFound;
  96. const catchAsync = (fn) => {
  97. return (req, res, next) => {
  98. fn(req, res, next).catch(next);
  99. };
  100. };
  101. exports.catchAsync = catchAsync;
  102. //# sourceMappingURL=errorHandler.js.map