如何在JavaScript中创建自定义错误?


214

出于某种原因,在以下代码段中,似乎构造函数委托不起作用:

function NotImplementedError() { 
  Error.apply(this, arguments); 
}
NotImplementedError.prototype = new Error();

var nie = new NotImplementedError("some message");
console.log("The message is: '"+nie.message+"'")

运行此给出The message is: ''。关于为什么的任何想法,或者是否有更好的方法来创建新的Error子类?我不知道apply的本地Error构造函数是否存在问题?


更改后,nie instanceof NotImplementedError断言是否有效?我认为,要使其正常工作,您需要明确定义NotImplementedError.prototype.constructor。
jayarjo 2011年

下次,请删除不需要的所有多余代码来演示您的问题。此外,wtc是js.jar吗?是否需要重现该问题?
英国电信

2
编辑了这个问题,使它在10秒而不是10分钟内就可以理解
BT

我创建了一个继承/类库,可以正确地从Error类型继承:github.com/fresheneesz/proto
BT

1
jsfiddle提供了一些最佳答案。
Nate

Answers:


193

更新代码以将原型分配给Error.prototype以及instanceof和您的assert工作。

function NotImplementedError(message) {
    this.name = "NotImplementedError";
    this.message = (message || "");
}
NotImplementedError.prototype = Error.prototype;

但是,我只是抛出您自己的对象并只检查name属性。

throw {name : "NotImplementedError", message : "too lazy to implement"}; 

根据评论进行编辑

在查看了注释并试图记住为什么要分配原型Error.prototype而不是new Error()像Nicholas Zakas在他的文章中所做的那样之后,我使用以下代码创建了一个jsFiddle

function NotImplementedError(message) {
  this.name = "NotImplementedError";
  this.message = (message || "");
}
NotImplementedError.prototype = Error.prototype;

function NotImplementedError2(message) {
  this.message = (message || "");
}
NotImplementedError2.prototype = new Error();

try {
  var e = new NotImplementedError("NotImplementedError message");
  throw e;
} catch (ex1) {
  console.log(ex1.stack);
  console.log("ex1 instanceof NotImplementedError = " + (ex1 instanceof NotImplementedError));
  console.log("ex1 instanceof Error = " + (ex1 instanceof Error));
  console.log("ex1.name = " + ex1.name);
  console.log("ex1.message = " + ex1.message);
}

try {
  var e = new NotImplementedError2("NotImplementedError2 message");
  throw e;
} catch (ex1) {
  console.log(ex1.stack);
  console.log("ex1 instanceof NotImplementedError2 = " + (ex1 instanceof NotImplementedError2));
  console.log("ex1 instanceof Error = " + (ex1 instanceof Error));
  console.log("ex1.name = " + ex1.name);
  console.log("ex1.message = " + ex1.message);
}

控制台输出是这个。

undefined
ex1 instanceof NotImplementedError = true
ex1 instanceof Error = true
ex1.name = NotImplementedError
ex1.message = NotImplementedError message
Error
    at window.onload (http://fiddle.jshell.net/MwMEJ/show/:29:34)
ex1 instanceof NotImplementedError2 = true
ex1 instanceof Error = true
ex1.name = Error
ex1.message = NotImplementedError2 message

这确认了我遇到的“问题”是错误的堆栈属性new Error()是创建的行号,而不是throw e发生的行号。但是,这可能比具有NotImplementedError.prototype.name = "NotImplementedError"影响Error对象的线的副作用更好。

此外,请注意NotImplementedError2,当我没有.name明确设置时,它等于“错误”。但是,如评论中所述,因为该版本将原型设置为new Error(),所以我可以进行设置NotImplementedError2.prototype.name = "NotImplementedError2"并确定。


45
最佳答案,但是Error.prototype直接采取可能是不好的形式。如果您以后想添加一个NotImplementedError.prototype.toString对象,现在可以使用别名Error.prototype.toString-更好NotImplementedError.prototype = new Error()
Cdleary

4
在所有这些原型方面,我还是有些失落。为什么在您的示例中,将名称分配给this.name而不是NotImplementedError.prototype.name?请您回答,这对我的理解至关重要:)
jayarjo 2011年

27
根据code.google.com/p/chromium/issues/detail?id=228909的描述 subclass.prototype = new Error(),表格格式不正确。您应该使用subclass.prototype = Object.create(superclass.prototype)代替。我希望它也可以解决堆栈跟踪问题。
吉利

8
获得有意义的stacktrace的简单技巧是在构造函数中生成错误并保存其堆栈。它将为构造函数提供适当的调用堆栈+ 1行(这是适当的回报):this.stack = new Error().stack;
Meredian

6
-1; 这是错误的。这样做NotImplementedError.prototype = Error.prototype;不会使instanceof治疗NotImplementedError作为一个子类Error,这让instanceof他们享受作为完全相同的类。如果将以上代码粘贴到控制台中,然后尝试new Error() instanceof NotImplementedError将得到true,这显然是错误的。
Mark Amery's

87

以上所有答案都很糟糕-确实如此。甚至有107起!真正的答案是:

从Error对象继承-message属性在哪里?

TL; DR:

答:之所以message未设置,是因为Error该函数返回一个新的Error对象,并且不会this以任何方式进行操作。

B.做到这一点的方法是从构造函数返回apply的结果,以及以通常的复杂javascript方式设置原型:

function MyError() {
    var temp = Error.apply(this, arguments);
    temp.name = this.name = 'MyError';
    this.message = temp.message;
    if(Object.defineProperty) {
        // getter for more optimizy goodness
        /*this.stack = */Object.defineProperty(this, 'stack', { 
            get: function() {
                return temp.stack
            },
            configurable: true // so you can change it if you want
        })
    } else {
        this.stack = temp.stack
    }
}
//inherit prototype using ECMAScript 5 (IE 9+)
MyError.prototype = Object.create(Error.prototype, {
    constructor: {
        value: MyError,
        writable: true,
        configurable: true
    }
});

var myError = new MyError("message");
console.log("The message is: '" + myError.message + "'"); // The message is: 'message'
console.log(myError instanceof Error); // true
console.log(myError instanceof MyError); // true
console.log(myError.toString()); // MyError: message
console.log(myError.stack); // MyError: message \n 
// <stack trace ...>


 
//for EMCAScript 4 or ealier (IE 8 or ealier), inherit prototype this way instead of above code:
/*
var IntermediateInheritor = function() {};
IntermediateInheritor.prototype = Error.prototype;
MyError.prototype = new IntermediateInheritor();
*/

您可能会做一些技巧来枚举tmpError的所有不可枚举属性来设置它们,而不是只显式地设置stackand message,但是ie <9中不支持这种技巧。


2
该解决方案还适用于实例化具有现有错误的自定义错误。如果您使用的是第三方库,并且想用自己的自定义类型包装现有错误,则其他方法将无法正常工作。仅供参考,您可以通过向普通错误传递现有错误来实例化它们。
凯尔·穆勒

1
你不应该return this在构造函数中。
OnurYıldırım2015年

13
我对此方法做了一些简化和改进:jsbin.com/rolojuhuya/1/edit?js,console
Matt Kantor

3
@MattKantor也许可以给出答案?我想我最喜欢你。
mpoisot 2015年

2
相反temp.name = this.name = 'MyError',您可以这样做temp.name = this.name = this.constructor.name。这样,它也适用于的子类MyError
Jo Liss 2015年

45

在ES2015中,您可以使用它class来干净地执行此操作:

class NotImplemented extends Error {
  constructor(message = "", ...args) {
    super(message, ...args);
    this.message = message + " has not yet been implemented.";
  }
}

这不修改全局Error原型,允许您自定义messagename以及其他属性,并正确捕获堆栈。它也很可读。

当然,您可能需要使用某种工具,例如babel您的代码是否将在较旧的浏览器上运行。


23

如果有人对如何创建自定义错误获取堆栈跟踪感到好奇:

function CustomError(message) {
  this.name = 'CustomError';
  this.message = message || '';
  var error = new Error(this.message);
  error.name = this.name;
  this.stack = error.stack;
}
CustomError.prototype = Object.create(Error.prototype);

try {
  throw new CustomError('foobar');
}
catch (e) {
  console.log('name:', e.name);
  console.log('message:', e.message);
  console.log('stack:', e.stack);
}

7

标准的这一部分可以解释为什么Error.apply调用不初始化对象:

15.11.1作为函数调用的错误构造函数

当Error作为函数而不是构造函数调用时,它将创建并初始化一个新的Error对象。因此,函数调用Error(...)等效于具有相同参数的对象创建表达式new Error(...)。

在这种情况下,该Error函数可能确定未将其作为构造函数调用,因此它返回一个新的Error实例,而不是初始化该this对象。

使用以下代码进行测试似乎可以证明这实际上是正在发生的事情:

function NotImplementedError() { 
   var returned = Error.apply(this, arguments);
   console.log("returned.message = '" + returned.message + "'");
   console.log("this.message = '" + this.message + "'");
}
NotImplementedError.prototype = new Error();

var nie = new NotImplementedError("some message");

运行此命令时将生成以下输出:

returned.message = 'some message'
this.message = ''

如何使用自定义错误类进行模拟?例如,如何将我的自定义错误类同时用作创建实例的函数和构造函数?
莉亚·海斯

不,这不是真的。如果返回新的Error实例,则他的msg属性将起作用。
英国电信

@BT新实例上的msg属性如何影响thisin中的msg属性Error.apply(this, arguments);?我是说这里对Error的调用正在构造一个新对象,该对象将被丢弃;没有初始化分配给的已构造对象nie
戴夫

@BT我添加了一些示例代码,希望可以使我想说的更加清楚。
戴夫

@Dave我可能在这里误解了目的,但是您的NotImplementedError实现不应该返回returned变量吗?
13年

7
function InvalidValueError(value, type) {
    this.message = "Expected `" + type.name + "`: " + value;
    var error = new Error(this.message);
    this.stack = error.stack;
}
InvalidValueError.prototype = new Error();
InvalidValueError.prototype.name = InvalidValueError.name;
InvalidValueError.prototype.constructor = InvalidValueError;

3
这是最好的答案。它是简洁的,以这种方式创建的异常将在所有情况下均正常运行。它还保留了堆栈跟踪,这在非平凡的应用程序中非常重要。我只会将“ prototype = new Error()”替换为“ prototype = Object.create(Error.prototype)”。对于Node.js,有一个小型图书馆可以为您提供帮助:npmjs.com/package/node-custom-errors
Lukasz Korzybski

6

我有与此类似的问题。我的错误需求是一个instanceofErrorNotImplemented,而且还需要产生在控制台连贯回溯。

我的解决方案:

var NotImplemented = (function() {
  var NotImplemented, err;
  NotImplemented = (function() {
    function NotImplemented(message) {
      var err;
      err = new Error(message);
      err.name = "NotImplemented";
      this.message = err.message;
      if (err.stack) this.stack = err.stack;
    }
    return NotImplemented;
  })();
  err = new Error();
  err.name = "NotImplemented";
  NotImplemented.prototype = err;

  return NotImplemented;
}).call(this);

// TEST:
console.log("instanceof Error: " + (new NotImplemented() instanceof Error));
console.log("instanceof NotImplemented: " + (new NotImplemented() instanceofNotImplemented));
console.log("message: "+(new NotImplemented('I was too busy').message));
throw new NotImplemented("just didn't feel like it");

使用node.js运行的结果:

instanceof Error: true
instanceof NotImplemented: true
message: I was too busy

/private/tmp/t.js:24
throw new NotImplemented("just didn't feel like it");
      ^
NotImplemented: just didn't feel like it
    at Error.NotImplemented (/Users/colin/projects/gems/jax/t.js:6:13)
    at Object.<anonymous> (/Users/colin/projects/gems/jax/t.js:24:7)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.runMain (module.js:487:10)
    at process.startup.processNextTick.process._tickCallback (node.js:244:9)

该错误通过了我的所有3条条件,尽管该stack属性是非标准的,但大多数较新的浏览器均支持该错误,在我的情况下是可以接受的。


5

根据Joyent的观点,您不应该对stack属性感到困惑(我在此处给出的很多答案中都可以看到),因为它会对性能产生负面影响。他们说的是:

堆栈:通常,请勿对此感到困惑。甚至不要增加它。V8仅在有人实际读取属性时才进行计算,从而极大地提高了可处理错误的性能。如果您只是为了增加属性而阅读该属性,那么即使您的呼叫者不需要该堆栈,您也将最终要支付费用。

我喜欢并且想提到他们包装原始错误的想法,这是传递堆栈的好方法。

因此,考虑到上述情况,这就是我如何创建自定义错误:

es5版本:

function RError(options) {
    options = options || {}; // eslint-disable-line no-param-reassign
    this.name = options.name;
    this.message = options.message;
    this.cause = options.cause;

    // capture stack (this property is supposed to be treated as private)
    this._err = new Error();

    // create an iterable chain
    this.chain = this.cause ? [this].concat(this.cause.chain) : [this];
}
RError.prototype = Object.create(Error.prototype, {
    constructor: {
        value: RError,
        writable: true,
        configurable: true
    }
});

Object.defineProperty(RError.prototype, 'stack', {
    get: function stack() {
        return this.name + ': ' + this.message + '\n' + this._err.stack.split('\n').slice(2).join('\n');
    }
});

Object.defineProperty(RError.prototype, 'why', {
    get: function why() {
        var _why = this.name + ': ' + this.message;
        for (var i = 1; i < this.chain.length; i++) {
            var e = this.chain[i];
            _why += ' <- ' + e.name + ': ' + e.message;
        }
        return _why;
    }
});

// usage

function fail() {
    throw new RError({
        name: 'BAR',
        message: 'I messed up.'
    });
}

function failFurther() {
    try {
        fail();
    } catch (err) {
        throw new RError({
            name: 'FOO',
            message: 'Something went wrong.',
            cause: err
        });
    }
}

try {
    failFurther();
} catch (err) {
    console.error(err.why);
    console.error(err.stack);
    console.error(err.cause.stack);
}

es6版本:

class RError extends Error {
    constructor({name, message, cause}) {
        super();
        this.name = name;
        this.message = message;
        this.cause = cause;
    }
    [Symbol.iterator]() {
        let current = this;
        let done = false;
        const iterator = {
            next() {
                const val = current;
                if (done) {
                    return { value: val, done: true };
                }
                current = current.cause;
                if (!val.cause) {
                    done = true;
                }
                return { value: val, done: false };
            }
        };
        return iterator;
    }
    get why() {
        let _why = '';
        for (const e of this) {
            _why += `${_why.length ? ' <- ' : ''}${e.name}: ${e.message}`;
        }
        return _why;
    }
}

// usage

function fail() {
    throw new RError({
        name: 'BAR',
        message: 'I messed up.'
    });
}

function failFurther() {
    try {
        fail();
    } catch (err) {
        throw new RError({
            name: 'FOO',
            message: 'Something went wrong.',
            cause: err
        });
    }
}

try {
    failFurther();
} catch (err) {
    console.error(err.why);
    console.error(err.stack);
    console.error(err.cause.stack);
}

我已将解决方案放入模块中,这里是:https : //www.npmjs.com/package/rerror


3

我喜欢这样:

  • 利用名称,以便toString()抛出"{code}: {message}"
  • 将相同的东西返回给super,以便它在stacktrace中看起来相同
  • 将代码附加到,error.code因为在代码中检查/解析代码比检查消息要好,例如,您可能希望对其进行本地化
  • 将邮件附加error.messageerror.toString()

class AppException extends Error {
  constructor(code, message) {
    const fullMsg = message ? `${code}: ${message}` : code;
    super(fullMsg);
    this.name = code;
    this.code = code;
    this.message = fullMsg;
  }
  
  toString() {
    return this.message;
  }
}

// Just a code
try {
  throw new AppException('FORBIDDEN');
} catch(e) {
  console.error(e);
  console.error(e.toString());
  console.log(e.code === 'FORBIDDEN');
}

// A code and a message
try {
  throw new AppException('FORBIDDEN', 'You don\'t have access to this page');
} catch(e) {
  console.error(e);
  console.error(e.toString());
  console.log(e.code === 'FORBIDDEN');
}


2

我只需要实现这样的事情,发现堆栈在我自己的错误实现中丢失了。我要做的是创建一个虚拟错误并从中检索堆栈:

My.Error = function (message, innerException) {
    var err = new Error();
    this.stack = err.stack; // IMPORTANT!
    this.name = "Error";
    this.message = message;
    this.innerException = innerException;
}
My.Error.prototype = new Error();
My.Error.prototype.constructor = My.Error;
My.Error.prototype.toString = function (includeStackTrace) {
    var msg = this.message;
    var e = this.innerException;
    while (e) {
        msg += " The details are:\n" + e.message;
        e = e.innerException;
    }
    if (includeStackTrace) {
        msg += "\n\nStack Trace:\n\n" + this.stack;
    }
    return msg;
}

这不会设置消息
BT

2

我使用了构造函数模式来创建新的错误对象。我定义了原型链,例如Error实例。请参阅MDN 错误构造函数参考。

您可以在要点上检查此片段。

实施方式

// Creates user-defined exceptions
var CustomError = (function() {
  'use strict';

  //constructor
  function CustomError() {
    //enforces 'new' instance
    if (!(this instanceof CustomError)) {
      return new CustomError(arguments);
    }
    var error,
      //handles the arguments object when is passed by enforcing a 'new' instance
      args = Array.apply(null, typeof arguments[0] === 'object' ? arguments[0] : arguments),
      message = args.shift() || 'An exception has occurred';

    //builds the message with multiple arguments
    if (~message.indexOf('}')) {
      args.forEach(function(arg, i) {
        message = message.replace(RegExp('\\{' + i + '}', 'g'), arg);
      });
    }

    //gets the exception stack
    error = new Error(message);
    //access to CustomError.prototype.name
    error.name = this.name;

    //set the properties of the instance
    //in order to resemble an Error instance
    Object.defineProperties(this, {
      stack: {
        enumerable: false,
        get: function() { return error.stack; }
      },
      message: {
        enumerable: false,
        value: message
      }
    });
  }

  // Creates the prototype and prevents the direct reference to Error.prototype;
  // Not used new Error() here because an exception would be raised here,
  // but we need to raise the exception when CustomError instance is created.
  CustomError.prototype = Object.create(Error.prototype, {
    //fixes the link to the constructor (ES5)
    constructor: setDescriptor(CustomError),
    name: setDescriptor('JSU Error')
  });

  function setDescriptor(value) {
    return {
      configurable: false,
      enumerable: false,
      writable: false,
      value: value
    };
  }

  //returns the constructor
  return CustomError;
}());

用法

CustomError构造函数可以接收许多参数来构建消息,例如

var err1 = new CustomError("The url of file is required"),
    err2 = new CustomError("Invalid Date: {0}", +"date"),
    err3 = new CustomError("The length must be greater than {0}", 4),
    err4 = new CustomError("Properties .{0} and .{1} don't exist", "p1", "p2");

throw err4;

这是自定义错误的外观:

自定义错误原型链


投票否决的人,您有论点或有否决理由吗?或只是不理解代码中的意图。
jherax

我只是注意到我在浏览该页面时一定不小心单击了向下投票按钮,而没有意识到(可能是从手机中浏览)。今天才浏览历史时才注意到。这绝对不是故意的,但是我不能撤消它,因为它已经超过了宽限期。您提供了翔实的答案,但绝对不值得。如果您进行修改,我会很乐意撤消降票。对于那个很抱歉。
jschr

1

构造函数必须像工厂方法一样,并返回所需的内容。如果需要其他方法/属性,可以在返回对象之前将它们添加到对象中。

function NotImplementedError(message) { return new Error("Not implemented", message); }

x = new NotImplementedError();

尽管我不确定为什么您需要这样做。为什么不只是使用new Error...?自定义例外在JavaScript(或可能是任何非类型化语言)中并没有增加多少。


2
您必须在JavaScript中启用“错误类型层次结构”或“对象值”,因为您只能指定一个catch块。在您的解决方案中,(x instanceof NotImplementedError)为false,在我的情况下这是不可接受的。
cdleary

1

这在Cesium DeveloperError中很好地实现了:

以简化形式:

var NotImplementedError = function(message) {
    this.name = 'NotImplementedError';
    this.message = message;
    this.stack = (new Error()).stack;
}

// Later on...

throw new NotImplementedError();

这很好用,除了堆栈将为错误构造函数包含额外的一行外,这可能是一个问题。
SystemParadox

另外,未通过error instanceof Error测试,这可能会有所帮助。
劳伦(Lauren)

1

这是我的实现:

class HttpError extends Error {
  constructor(message, code = null, status = null, stack = null, name = null) {
    super();
    this.message = message;
    this.status = 500;

    this.name = name || this.constructor.name;
    this.code = code || `E_${this.name.toUpperCase()}`;
    this.stack = stack || null;
  }

  static fromObject(error) {
    if (error instanceof HttpError) {
      return error;
    }
    else {
      const { message, code, status, stack } = error;
      return new ServerError(message, code, status, stack, error.constructor.name);
    }
  }

  expose() {
    if (this instanceof ClientError) {
      return { ...this };
    }
    else {
      return {
        name: this.name,
        code: this.code,
        status: this.status,
      }
    }
  }
}

class ServerError extends HttpError {}

class ClientError extends HttpError { }

class IncorrectCredentials extends ClientError {
  constructor(...args) {
    super(...args);
    this.status = 400;
  }
}

class ResourceNotFound extends ClientError {
  constructor(...args) {
    super(...args);
    this.status = 404;
  }
}

用法示例1:

app.use((req, res, next) => {
  try {
    invalidFunction();
  }
  catch (err) {
    const error = HttpError.fromObject(err);
    return res.status(error.status).send(error.expose());
  }
});

用法示例2:

router.post('/api/auth', async (req, res) => {
  try {
    const isLogged = await User.logIn(req.body.username, req.body.password);

    if (!isLogged) {
      throw new IncorrectCredentials('Incorrect username or password');
    }
    else {
      return res.status(200).send({
        token,
      });
    }
  }
  catch (err) {
    const error = HttpError.fromObject(err);
    return res.status(error.status).send(error.expose());
  }
});

0

下面的代码以无法使用为代价,instanceof保留了原始堆栈跟踪信息,并且不使用任何非标准技巧。

// the function itself
var fixError = function(err, name) {
    err.name = name;
    return err;
}

// using the function
try {
    throw fixError(new Error('custom error message'), 'CustomError');
} catch (e) {
    if (e.name == 'CustomError')
        console.log('Wee! Custom Error! Msg:', e.message);
    else
        throw e; // unhandled. let it propagate upwards the call stack
}

您要做的所有能够使用instanceof的操作都是抛出新的fixError而不是仅fixError
BT

@BT:不具有fixError以上功能。new调用时添加一个a 只会创建一个被丢弃的对象。
TJ Crowder 2015年

哦,我想我的意思使用“的instanceof fixError” -当然再“的instanceof错误”是行不通的。我想这是更糟糕..
BT

0

另一种选择,可能并非在所有环境中都有效。Aastast保证它可以在nodejs 0.8中使用。

function myError(msg){ 
      var e = new Error(msg); 
      _this = this; 
      _this.__proto__.__proto__ = e;
}

0

如果您使用的是Node / Chrome。以下代码片段将为您扩展符合以下要求的内容。

  • err instanceof Error
  • err instanceof CustomErrorType
  • [CustomErrorType]当创建一条消息时,console.log()返回
  • console.log()返回[CustomErrorType: message],创建时不显示任何消息
  • 抛出/堆栈可在错误创建时提供信息。
  • 在Node.JS和Chrome中效果最佳。
  • 将通过Chrome,Safari,Firefox和IE 8+中的instanceof检查,但在Chrome / Safari之外没有有效的堆栈。我可以接受,因为我可以在chrome中进行调试,但是需要特定错误类型的代码仍然可以跨浏览器运行。如果只需要Node,则可以轻松删除这些if语句,您很高兴

片段

var CustomErrorType = function(message) {
    if (Object.defineProperty) {
        Object.defineProperty(this, "message", {
            value : message || "",
            enumerable : false
        });
    } else {
        this.message = message;
    }

    if (Error.captureStackTrace) {
        Error.captureStackTrace(this, CustomErrorType);
    }
}

CustomErrorType.prototype = new Error();
CustomErrorType.prototype.name = "CustomErrorType";

用法

var err = new CustomErrorType("foo");

输出量

var err = new CustomErrorType("foo");
console.log(err);
console.log(err.stack);

[CustomErrorType: foo]
CustomErrorType: foo
    at Object.<anonymous> (/errorTest.js:27:12)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:906:3

/errorTest.js:30
        throw err;
              ^
CustomErrorType: foo
    at Object.<anonymous> (/errorTest.js:27:12)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:906:3

0

以下内容来自Mozilla官方文档Error,对我有用。

function NotImplementedError(message) {
    var instance = new Error(message);
    instance.name = 'NotImplementedError';

    Object.setPrototypeOf(instance, Object.getPrototypeOf(this));
    if (Error.captureStackTrace) {
        Error.captureStackTrace(instance, NotImplementedError);
    }
    return instance;
}

NotImplementedError.prototype = Object.create(Error.prototype, {
    constructor: {
        value: Error,
        enumerable: false,
        writable: true,
        configurable: true
    }
});

-1

为用户定义的错误类型的每个实例尝试一个新的原型对象。它使instanceof检查能够像往常一样运行,并且在Firefox和V8(Chome,nodejs)中正确报告了类型和消息。

function NotImplementedError(message){
    if(NotImplementedError.innercall===undefined){
        NotImplementedError.innercall = true;
        NotImplementedError.prototype = new Error(message);
        NotImplementedError.prototype.name = "NotImplementedError";
        NotImplementedError.prototype.constructor = NotImplementedError;

        return new NotImplementedError(message);
    }
    delete NotImplementedError.innercall;
}

请注意,其他条目将位于否则为正确的堆栈之前。


不起作用 试试:var a = new NotImplementedError('a'), b = new NotImplementedError('b');。现在a instanceof NotImplementedError == falseb instanceof NotImplementedError == true
jjrv

-1

这是最快的方法:

    let thisVar = false

    if (thisVar === false) {
            throw new Error("thisVar is false. It should be true.")
    }

-3

更简单的方法。您可以使您的对象继承自Error对象。例:

function NotImplementError(message)
{
    this.message = message;
    Error.call();
    Error.call(message);
} 

我们正在做的是使用函数Call()来调用Error类的构造函数,因此,与在其他面向对象的语言中实现类继承基本相同。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.