Как получить правильную обратную трассировку для пользовательского класса ошибок в NodeJS? - PullRequest
11 голосов
/ 10 декабря 2011

Мое понимание "правильного" способа создания пользовательского класса ошибок в JavaScript выглядит примерно так:

function MyError(message) {  
    this.name = "MyError";  
    this.message = message || "Default Message";  
}  
MyError.prototype = new Error();  
MyError.prototype.constructor = MyError;

(фрагмент кода, созданный из https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error.)

с NodeJS,если я попытаюсь проверить наличие ошибки такого типа, как:

var err = new MyError("whoops");
assert.ifError(err);

... обратная трассировка покажет контекст объекта Error, который я создал во время компиляции, чтобы он был прототипом для MyError, а не MyErrorобъект, который я создал с помощью "new MyError ()".

Есть ли способ получить правильные данные обратной трассировки для фактической ошибки, а не для прототипа?

Ответы [ 2 ]

34 голосов
/ 11 декабря 2011

Нам нужно вызвать суперфункцию - captureStackTrace

var util = require('util');

function MyError(message) {
  Error.call(this); //super constructor
  Error.captureStackTrace(this, this.constructor); //super helper method to include stack trace in error object

  this.name = this.constructor.name; //set our function’s name as error name.
  this.message = message; //set the error message
}

// inherit from Error
util.inherits(MyError, Error);

ОБНОВЛЕНИЕ:

Этот модуль узла можно использовать для простого расширения типов ошибок https://github.com/jayyvis/extend-error

2 голосов
/ 24 ноября 2015

@ Джей Кумар, здесь есть один хороший ответ. Однако, может быть, здесь есть другое подобное решение здесь

module.exports = function CustomError(message, extra) {
  Error.captureStackTrace(this, this.constructor);
  this.name = this.constructor.name;
  this.message = message;
  this.extra = extra;
};

require('util').inherits(module.exports, Error);

Error.call (this) - создает другой объект ошибки (тратит кучу времени) и вообще не трогает его

Поскольку ECMAScript6 может поддерживаться в последней версии Node.js. Ответ под ES6 можно отнести к этой ссылке .

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

Вот тестовые коды под Node v4.2.1

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

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

Выход:

MyError: test
    at MyError (/home/bsadmin/test/test.js:5:8)
    at Object.<anonymous> (/home/bsadmin/test/test.js:12: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
{ [MyError: test] name: 'MyError', extra: 13 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...