138

ES6 と Babel でエラーを拡張しようとしています。うまくいきません。

class MyError extends Error {
  constructor(m) {
    super(m);
  }
}

var error = new Error("ll");
var myerror = new MyError("ll");
console.log(error.message) //shows up correctly
console.log(myerror.message) //shows empty string

Error オブジェクトは正しいメッセージ セットを取得しません。

Babel REPL で試してください

今、私は SO でいくつかの解決策を見てきました (たとえば、ここ) が、それらはすべて非常に ES6-y ではないようです。素敵なES6の方法でそれを行うには? (それはバベルで働いています)

4

14 に答える 14

200

Karel Bílek の回答に基づいて、次のように少し変更しますconstructor

class ExtendableError extends Error {
  constructor(message) {
    super(message);
    this.name = this.constructor.name;
    if (typeof Error.captureStackTrace === 'function') {
      Error.captureStackTrace(this, this.constructor);
    } else { 
      this.stack = (new Error(message)).stack; 
    }
  }
}    

// now I can extend

class MyError extends ExtendableError {}

var myerror = new MyError("ll");
console.log(myerror.message);
console.log(myerror instanceof Error);
console.log(myerror.name);
console.log(myerror.stack);

これはMyError、ジェネリックではなく、スタックに出力されますError

また、エラー メッセージをスタック トレースに追加します。これは、Karel の例にはありませんでした。

また、captureStackTrace利用可能な場合は使用します。

Babel 6 では、これが機能するために transform-b​​uiltin-extend ( npm ) が必要です。

于 2015-09-23T21:10:21.947 に答える
27

これを最後に休ませるために。Babel 6 では、開発者がビルトインからの拡張をサポートしていないことは明らかです。このトリックは、 などには役立ちませんが、 には機能します。例外をスローできる言語のコア アイデアの 1 つは、カスタム エラーを許可することであるため、これは重要です。Promise は Error を拒否するように設計されているため、Promise がより便利になるため、これは二重に重要です。MapSetError

悲しいことに、ES2015 ではこれを古い方法で実行する必要があります。

Babel REPL での例

カスタム エラー パターン

class MyError {
  constructor(message) {
    this.name = 'MyError';
    this.message = message;
    this.stack = new Error().stack; // Optional
  }
}
MyError.prototype = Object.create(Error.prototype);

一方、これを可能にする Babel 6 用のプラグインがあります。

https://www.npmjs.com/package/babel-plugin-transform-b​​uiltin-extend

更新: (2016 年 9 月 29 日現在) いくつかのテストの後、babel.io がすべてのアサート (カスタム拡張エラーから拡張) を適切に考慮していないようです。しかし、Ember.JS では Error を拡張すると期待どおりに動作します: https://ember-twiddle.com/d88555a6f408174df0a4c8e0fd6b27ce

于 2016-03-08T04:18:58.390 に答える
7

引用

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

コールのthis.stack = (new Error()).stack;おかげでトリックは必要ありません。super()

this.stack = (new Error()).stack;上記のコードは、またはがBabelError.captureStackTrace(this, this.constructor.name);で呼び出されない限り、スタック トレースを出力できません。IMO、これはおそらく 1 つの問題です。

実際には、このコード スニペットの下Chrome consoleでスタック トレースを出力できます。Node.js v4.2.1

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

var myerr = new MyError("test");
console.log(myerr.stack);
console.log(myerr);

の出力Chrome console

MyError: test
    at MyError (<anonymous>:3:28)
    at <anonymous>:12:19
    at Object.InjectedScript._evaluateOn (<anonymous>:875:140)
    at Object.InjectedScript._evaluateAndWrap (<anonymous>:808:34)
    at Object.InjectedScript.evaluate (<anonymous>:664:21)

の出力Node.js

MyError: test
    at MyError (/home/bsadmin/test/test.js:5:8)
    at Object.<anonymous> (/home/bsadmin/test/test.js:11:13)
    at Module._compile (module.js:435:26)
    at Object.Module._extensions..js (module.js:442:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:311:12)
    at Function.Module.runMain (module.js:467:10)
    at startup (node.js:134:18)
    at node.js:961:3
于 2015-11-24T09:30:21.940 に答える
2

ES6でエラーを拡張しようとしています

そのclass MyError extends Error {…}構文は正しいです。

組み込みオブジェクトからの継承に関して、トランスパイラには依然として問題があることに注意してください。あなたの場合、

var err = super(m);
Object.assign(this, err);

問題を解決するようです。

于 2015-06-27T14:34:49.540 に答える
1

これは私のために働く:

/**
 * @class AuthorizationError
 * @extends {Error}
 */
export class AuthorizationError extends Error {
    message = 'UNAUTHORIZED';
    name = 'AuthorizationError';
}
于 2019-03-08T17:15:29.453 に答える