Error
を継承するカスタム例外を作成しようとしていますが、webpackがそれを気に入らないようです。このコードは、ノードREPLとchromeのコンソール[1]で直接動作しますが、webpack(バージョン:[email protected]β17)によってコンパイルされたノードまたはブラウザでは正常に動作しません。`Error` w/webpackを拡張するときに` toString`をオーバーライドできません
コンパイルされていないコード:
export default class Exception extends Error {
constructor(message, inner) {
super(message);
this.name = 'Exception';
this.message = message;
this.inner = inner;
if (typeof super.constructor.captureStackTrace === 'function') {
super.constructor.captureStackTrace(this, this.constructor);
} else {
const stack = (new super.constructor(message)).stack;
this.stack = stack.split('\n').slice(1).map(l => l.trim()).join('\n');
}
}
toString() {
let string = this.stack;
if (this.inner) {
const innerLines = this.inner.toString().split('\n');
const inner = innerLines.map(line => {
return line.replace(/^(\s+)/g, function($0, $1) {
return ` ${$1}`;
});
}).join('\n');
// eslint-disable-next-line prefer-template
string = (string + '\n' +
' Inner ' + inner);
}
return string;
}
}
関連試験:
describe('Exception',() => {
describe('toString',() => {
it('should return the `name`: `message` + `stack` (recursively if there are inner exceptions)',() => {
const innerMessage = 'foo bar!';
const outerMessage = 'bar foo!';
const inner = new Exception(innerMessage);
const outer = new Exception(outerMessage, inner);
expect(inner.toString())
.to.match(new RegExp(`Exception: ${innerMessage}`));
expect(outer.toString())
.to.match(new RegExp(`Exception: ${outerMessage}`))
.and.to.match(new RegExp(`Inner Exception: ${innerMessage}`));
});
});
});
失敗:
コンパイル1) Exception toString should return the `name`: `message` + `stack` (recursively if there are inner exceptions):
AssertionError: expected 'Exception: bar foo!' to match /Inner Exception: foo bar!/
at Context.<anonymous> (.test/test/unit/shared/lib/exceptions/exception.compiledtest:178:90)
:https://gist.github.com/dwick/4d29c679f5a1c8260f22d619c3167524
すべてが期待私として働きますf私はError
から継承しませんが、実際にはe instanceof Error
が好きです。
それは、コンストラクタ自体対Exception
のtoString
インスタンスをログインするときに何が起こっているかはかなり明らかだ:
> console.log('instance:', outer.toString.toString());
instance: function toString() { [native code] }
> console.log('prototype:', Exception.prototype.toString.toString());
prototype: function toString() {
var string = this.stack;
if (this.inner) {
var innerLines = this.inner.toString().split('\n');
var inner = innerLines.map(function (line) {
return line.replace(/^(\s+)/g, function ($0, $1) {
return ' ' + $1;
});
}).join('\n');
// eslint-disable-next-line prefer-template
string = string + '\n' + ' Inner ' + inner;
}
return string;
}
なぜ、どのようにこの問題を解決するにとしてだけ混乱し。 FWIW私はまた、同じ結果を試してみました:
class Exception extends Error { ... }
Exception.prototype.toString = ...
実際にはバベルの不具合が考えられる:https://babeljs.io/docs/usage/caveats/#classes。 https://github.com/loganfsmyth/babel-plugin-transform-builtin-extend –
古典的なプロトタイプ継承で再実装することができます:https://github.com/addyosmani/es6-equivalents -in-es5#classes –