You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

console.log内错误抛出顺序异常?自定义Error技术问询

为什么你的console.log中错误抛出顺序不符合预期?

首先咱们先拆解你自定义错误实现里的几个关键问题,这些问题直接导致了错误栈或者输出表现不符合预期:

1. 自定义错误的constructor未正确重置

你用CustomError.prototype = Object.create(Error.prototype)实现了继承,但没有把CustomError.prototype.constructor指向自身。这会导致错误对象的构造函数标识混乱,不仅影响instanceof的准确性,还可能让日志输出里的错误类型显示异常。

2. 错误栈(stack)的生成时机错了

你在CustomError构造函数里直接赋值this.stack = (new Error()).stack,这个栈是构造函数内部创建匿名Error时的调用栈,而不是throw语句执行时的栈。比如当你在foo()里抛出CustomError时,栈的顶部会显示CustomError构造函数,而不是foo(),这就造成了错误栈顺序“错位”的错觉。


解决办法

修正自定义错误的实现

我们用更标准的方式实现自定义错误,同时利用Error.captureStackTrace(Node.js和现代浏览器都支持)生成正确的栈追踪:

function CustomError(message) {
  // 先调用Error构造函数初始化基础属性
  const baseError = new Error(message);
  // 捕获栈追踪,第二个参数排除构造函数本身,让栈从调用它的地方开始
  Error.captureStackTrace(this, CustomError);
  
  this.name = 'CustomError';
  this.message = message;
  // 兼容旧环境可以直接复用baseError的栈
  this.stack = baseError.stack;
}

// 正确设置原型继承
CustomError.prototype = Object.create(Error.prototype);
// 重置constructor指向自身
CustomError.prototype.constructor = CustomError;

如果你的环境支持ES6,用class写法会更简洁直观:

class CustomError extends Error {
  constructor(message) {
    super(message);
    this.name = 'CustomError';
    // 手动捕获栈,确保栈从抛出位置开始
    Error.captureStackTrace(this, this.constructor);
  }
}

验证效果

用修正后的代码运行你的逻辑:

function foo() {
  throw new CustomError('custom error message');
}

try {
  foo();
} catch (err) {
  console.log(err);
}

此时console.log输出的错误栈会正确显示错误是从foo()函数抛出的,顺序完全符合预期。

另外,如果是错误信息和其他日志的输出顺序混乱(比如错误日志跑到普通日志后面),那是因为部分环境会异步格式化错误对象。这时候可以把错误转为字符串输出,比如console.log(err.stack),就能保证顺序正确了。

内容的提问来源于stack exchange,提问作者Matus Dubrava

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:39:44