全部学科
NodeJS全栈
nodejs
Python全栈
python
小程序首页
📅 2026-05-15 7 分钟 ✍️ juanwangdev

Node.js 日志与错误处理

良好的日志和错误处理机制是应用稳定性的基础。

日志级别

标准日志级别

级别说明场景
error错误异常、失败
warn警告潜在问题
info信息重要事件
debug调试详细信息
trace追踪最详细信息

console 日志

基本方法

JavaScript
console.log('普通日志');
console.info('信息日志');
console.warn('警告日志');
console.error('错误日志');
console.debug('调试日志');

结构化日志

JavaScript
// 格式化输出
console.log(JSON.stringify({
  level: 'info',
  message: '用户登录',
  userId: '12345',
  timestamp: new Date().toISOString()
}));

错误对象

Error 类型

JavaScript
// 基本错误
const err = new Error('发生错误');
console.log(err.message);   // 错误消息
console.log(err.stack);      // 堆栈追踪

// 内置错误类型
const typeErr = new TypeError('类型错误');
const rangeErr = new RangeError('范围错误');
const refErr = new ReferenceError('引用错误');
const syntaxErr = new SyntaxError('语法错误');

自定义错误

JavaScript
class AppError extends Error {
  constructor(message, code) {
    super(message);
    this.name = 'AppError';
    this.code = code;
    this.timestamp = new Date().toISOString();
  }
}

throw new AppError('用户不存在', 404);

同步错误处理

try-catch

JavaScript
function divide(a, b) {
  if (b === 0) {
    throw new Error('除数不能为零');
  }
  return a / b;
}

try {
  const result = divide(10, 0);
} catch (err) {
  console.error('捕获错误:', err.message);
} finally {
  console.log('清理资源');
}

异步错误处理

Promise 错误

JavaScript
// catch 捕获
fetch('api/data')
  .then(res => res.json())
  .then(data => console.log(data))
  .catch(err => console.error('请求失败:', err.message));

// async/await
async function fetchData() {
  try {
    const res = await fetch('api/data');
    const data = await res.json();
    return data;
  } catch (err) {
    console.error('获取数据失败:', err.message);
    throw err;
  }
}

全局错误处理

未捕获异常

JavaScript
process.on('uncaughtException', (err, origin) => {
  console.error('未捕获异常:', err.message);
  console.error('来源:', origin);
  // 记录日志后退出
  process.exit(1);
});

未处理的 Promise 拒绝

JavaScript
process.on('unhandledRejection', (reason, promise) => {
  console.error('未处理的 Promise 拒绝:', reason);
});

// 正确做法:始终处理 Promise 拒绝
asyncFunction().catch(err => {
  console.error('处理错误:', err);
});

日志框架

使用 winston

JavaScript
const winston = require('winston');

const logger = winston.createLogger({
  level: 'info',
  format: winston.format.json(),
  transports: [
    new winston.transports.Console(),
    new winston.transports.File({ filename: 'error.log', level: 'error' }),
    new winston.transports.File({ filename: 'combined.log' })
  ]
});

// 使用
logger.info('服务启动', { port: 3000 });
logger.error('数据库连接失败', { error: err.message });

使用 pino

JavaScript
const pino = require('pino');

const logger = pino({
  level: 'info',
  transport: {
    target: 'pino-pretty'
  }
});

logger.info('用户登录');
logger.error({ err }, '请求处理失败');

错误处理中间件

Express 错误处理

JavaScript
// 错误处理中间件(必须放在最后)
app.use((err, req, res, next) => {
  console.error('错误:', err.message);

  res.status(err.status || 500).json({
    error: {
      message: err.message,
      code: err.code
    }
  });
});

// 调用 next(err) 触发
app.get('/user/:id', (req, res, next) => {
  const user = findUser(req.params.id);
  if (!user) {
    return next(new Error('用户不存在'));
  }
  res.json(user);
});

注意事项

  • 生产环境使用专业日志框架(winston、pino)
  • 不要吞掉错误,确保所有错误都被处理或记录
  • uncaughtException 后应退出进程
  • 日志避免包含敏感信息(密码、令牌)

要点总结

  • 使用日志级别区分信息重要性
  • try-catch 处理同步错误
  • Promise 使用 .catch()try/await
  • process.on('uncaughtException') 捕获全局异常
  • Express 错误中间件统一处理请求错误

📝 发现内容有误?点击此处直接编辑

← 上一篇 Node.js 性能分析工具(Clinic.js)
下一篇 → Node.js 环境变量管理(dotenv)
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库