在 3.23.2 版中,新功能“Sensible non-Error exception serializer”(#1253)导致使用es6-error
(https://www.npmjs.com/package/es6-error)产生的错误更改错误内容。
这行中的captureException
函数正在更改:
options = this._getCaptureExceptionOptionsFromPlainObject(options, ex);
更具体地说,这是我的代码:
import ExtendableError from 'es6-error'
class CustomError extends ExtendableError {
constructor(code, message) {
super(message)
this.name ='CustomError'
this.code = code
}
}
export default CustomError
然后在代码中:
Raven.captureException(new CustomError('code123', 'not working'));
// this will cause the error message to be "Non-Error exception captured with keys: code"
这似乎是 JS 模块的一种非常奇怪的行为。
当您使用:
import ExtendableError from 'es6-error'
class CustomError extends ExtendableError {
constructor(code, message) {
super(message)
this.name ='CustomError'
this.code = code
}
}
function isPlainObject(what) {
return Object.prototype.toString.call(what) === '[object Object]';
}
function isError(value) {
switch ({}.toString.call(value)) {
case '[object Error]':
return true;
case '[object Exception]':
return true;
case '[object DOMException]':
return true;
default:
return value instanceof Error;
}
}
function isErrorEvent(value) {
return Object.prototype.toString.call(value) === '[object ErrorEvent]';
}
var ex = new CustomError('code123', 'not working');
console.log('isPlainObject:', isPlainObject(ex))
console.log('isError:', isError(ex))
console.log('isErrorEvent:', isErrorEvent(ex))
它会错误地报告true/true/false
。
但是,当您将import
语句替换为代码本身时
class ExtendableError extends Error {
constructor(message = '') {
super(message);
// extending Error is weird and does not propagate `message`
Object.defineProperty(this, 'message', {
configurable: true,
enumerable : false,
value : message,
writable : true,
});
Object.defineProperty(this, 'name', {
configurable: true,
enumerable : false,
value : this.constructor.name,
writable : true,
});
if (Error.hasOwnProperty('captureStackTrace')) {
Error.captureStackTrace(this, this.constructor);
return;
}
Object.defineProperty(this, 'stack', {
configurable: true,
enumerable : false,
value : (new Error(message)).stack,
writable : true,
});
}
}
它会正确报告false/true/false
。
我将尝试调试为什么会这样,如果我无法找出答案,我们将交换检查以首先通过isError
。
@zivl当您在本地测试它并使用该代码创建自己的custom-error.js
文件并将其作为模块导入时,它可以正常工作。
问题是这个库没有“按原样”导出它的代码,而是使用 Babel 预编译它。
所以它最终是“有点”错误,但不是真的。 它是一个继承特定属性的普通对象,并且将prototype
设置为Error
本身。
不幸的是,除了更改检查顺序之外,没有办法解决这个问题,因为它就像一个“薛定谔错误”。 它既是又不是错误。
@zivl在3.23.3
中发布。 感谢您的报告!
最有用的评论
@zivl当您在本地测试它并使用该代码创建自己的
custom-error.js
文件并将其作为模块导入时,它可以正常工作。问题是这个库没有“按原样”导出它的代码,而是使用 Babel 预编译它。
所以它最终是“有点”错误,但不是真的。 它是一个继承特定属性的普通对象,并且将
prototype
设置为Error
本身。不幸的是,除了更改检查顺序之外,没有办法解决这个问题,因为它就像一个“薛定谔错误”。 它既是又不是错误。