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

Node.js 错误对象与自定义错误

Error 对象是 Node.js 错误处理的核心。

Error 对象属性

标准属性

JavaScript
const err = new Error('出错了');

console.log(err.message);  // '出错了' - 错误描述
console.log(err.name);     // 'Error' - 错误类型名
console.log(err.stack);    // 堆栈追踪字符串

扩展属性

JavaScript
const err = new Error('数据库连接失败');
err.code = 'ECONNREFUSED';
err.statusCode = 500;
err.details = { host: 'localhost', port: 3306 };

console.log(err.code);       // 'ECONNREFUSED'
console.log(err.statusCode); // 500

内置错误类型

Error 类型列表

类型说明触发场景
Error通用错误throw new Error()
TypeError类型错误对错误类型调用方法
RangeError范围错误数值超出有效范围
ReferenceError引用错误访问未定义变量
SyntaxError语法错误解析语法错误
URIErrorURI错误encodeURI/decodeURI 失败
SystemError系统错误文件/网络操作失败

使用示例

JavaScript
// TypeError
try {
  null.method();
} catch (err) {
  console.log(err.name);    // TypeError
  console.log(err.message); // Cannot read property 'method' of null
}

// RangeError
try {
  new Array(-1);
} catch (err) {
  console.log(err.name);    // RangeError
}

// ReferenceError
try {
  console.log(undefinedVar);
} catch (err) {
  console.log(err.name);    // ReferenceError
}

系统错误属性

JavaScript
// 系统错误(fs、net等)额外属性
fs.readFile('notexist.txt', (err, data) => {
  if (err) {
    console.log(err.code);      // 'ENOENT' - 错误码
    console.log(err.syscall);   // 'open' - 系统调用
    console.log(err.path);      // 'notexist.txt' - 文件路径
    console.log(err.errno);     // -2 - 错误号
  }
});

自定义错误类

基本自定义错误

JavaScript
class ValidationError extends Error {
  constructor(message) {
    super(message);
    this.name = 'ValidationError';
  }
}

throw new ValidationError('输入验证失败');

添加额外属性

JavaScript
class ValidationError extends Error {
  constructor(message, field, value) {
    super(message);
    this.name = 'ValidationError';
    this.field = field;
    this.value = value;
    this.statusCode = 400;
  }
}

// 使用
try {
  throw new ValidationError('邮箱格式错误', 'email', 'invalid-email');
} catch (err) {
  console.log({
    name: err.name,
    message: err.message,
    field: err.field,
    value: err.value,
    statusCode: err.statusCode
  });
}

业务错误类

JavaScript
class BusinessError extends Error {
  constructor(message, code, statusCode = 500) {
    super(message);
    this.name = 'BusinessError';
    this.code = code;
    this.statusCode = statusCode;
    this.timestamp = new Date().toISOString();
    this.isOperational = true;  // 标记为可操作错误
  }
}

class NotFoundError extends BusinessError {
  constructor(resource) {
    super(`${resource} 不存在`, 'NOT_FOUND', 404);
    this.name = 'NotFoundError';
    this.resource = resource;
  }
}

class UnauthorizedError extends BusinessError {
  constructor(message = '未授权访问') {
    super(message, 'UNAUTHORIZED', 401);
    this.name = 'UnauthorizedError';
  }
}

数据库错误

JavaScript
class DatabaseError extends Error {
  constructor(message, query, originalError) {
    super(message);
    this.name = 'DatabaseError';
    this.query = query;
    this.originalError = originalError;
    this.statusCode = 500;
  }
}

try {
  await db.query('SELECT * FROM users');
} catch (err) {
  throw new DatabaseError('查询失败', 'SELECT * FROM users', err);
}

错误类使用

分类处理

JavaScript
function handleError(err) {
  if (err instanceof ValidationError) {
    return {
      status: err.statusCode,
      body: { error: err.message, field: err.field }
    };
  }

  if (err instanceof NotFoundError) {
    return {
      status: 404,
      body: { error: err.message }
    };
  }

  if (err instanceof DatabaseError) {
    logger.error('数据库错误:', err.originalError);
    return {
      status: 500,
      body: { error: '服务器内部错误' }
    };
  }

  // 未知错误
  logger.error(err.stack);
  return {
    status: 500,
    body: { error: '未知错误' }
  };
}

Express 中使用

JavaScript
// 路由中使用
app.get('/user/:id', async (req, res, next) => {
  const user = await User.findById(req.params.id);
  if (!user) {
    return next(new NotFoundError('用户'));
  }
  res.json(user);
});

// 错误处理中间件
app.use((err, req, res, next) => {
  const statusCode = err.statusCode || 500;
  res.status(statusCode).json({
    error: err.message,
    code: err.code
  });
});

错误堆栈

获取堆栈

JavaScript
const err = new Error('测试');
console.log(err.stack);

// 输出格式
// Error: 测试
//     at Object.<anonymous> (/path/file.js:10:11)
//     at Module._compile (internal/modules/cjs/loader.js:...)

自定义堆栈捕获点

JavaScript
class CustomError extends Error {
  constructor(message) {
    super(message);
    // 捕获当前点堆栈,排除构造函数
    Error.captureStackTrace(this, CustomError);
  }
}

注意事项

  • 自定义错误必须继承 Error
  • 调用 super(message) 设置 message
  • 设置 name 属性标识错误类型
  • 添加 statusCode 方便 HTTP 响应
  • 使用 isOperational 区分可恢复错误

要点总结

  • Error 有 message、name、stack 属性
  • 系统错误有 code、syscall、path 等
  • 自定义错误继承 Error 并扩展属性
  • 添加 statusCode 和 code 便于处理
  • 使用 instanceof 分类处理错误

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

← 上一篇 Node.js 错误处理基础
下一篇 → Node.js ESLint 与代码风格检查
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

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

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