KOA技术分享

专注 Koa.js 框架的编程知识分享

Koa 应用的错误处理与日志记录方案

统一错误捕获中间件

app.use(async (ctx, next) => {
  try {
    await next();
  } catch (err) {
    ctx.status = err.status || err.statusCode || 500;
    ctx.body = {
      success: false,
      message: err.message || '服务器内部错误'
    };
    ctx.app.emit('error', err, ctx);
  }
});

日志记录实现

const fs = require('fs');
const path = require('path');

const logDir = path.join(__dirname, 'logs');
if (!fs.existsSync(logDir)) {
  fs.mkdirSync(logDir);
}

function log(message) {
  const date = new Date().toISOString();
  const logFile = path.join(logDir, `${new Date().toDateString()}.log`);
  fs.appendFileSync(logFile, `[${date}] ${message}\n`);
}

app.on('error', (err, ctx) => {
  log(`Error: ${err.message} | URL: ${ctx.url} | IP: ${ctx.ip}`);
});

请求日志中间件

app.use(async (ctx, next) => {
  const start = Date.now();
  await next();
  const ms = Date.now() - start;
  log(`${ctx.method} ${ctx.url} ${ctx.status} ${ms}ms`);
});

自定义错误类

class AppError extends Error {
  constructor(message, status = 500) {
    super(message);
    this.status = status;
  }
}

class NotFoundError extends AppError {
  constructor(message = '资源不存在') {
    super(message, 404);
  }
}

class ValidationError extends AppError {
  constructor(message = '参数验证失败') {
    super(message, 400);
  }
}

生产环境错误处理

app.on('error', (err, ctx) => {
  if (process.env.NODE_ENV === 'production') {
    // 发送告警通知
    sendAlert(err);
  } else {
    console.error(err);
  }
});
← 上一篇:Koa 项目中集成 MySQL 与 Sequelize