代码之家  ›  专栏  ›  技术社区  ›  Anthony O.

如何在JavaScript错误中指定“caused by”?

  •  32
  • Anthony O.  · 技术社区  · 11 年前

    在我的NodeJS程序中,我解析了一些用户JSON文件。

    所以我使用:

    this.config = JSON.parse(fs.readFileSync(path));
    

    问题是,如果json文件格式不正确,抛出的错误如下:

    undefined:55
                },
                ^
    SyntaxError: Unexpected token }
        at Object.parse (native)
        at new MyApp (/path/to/docker/lib/node_modules/myApp/lib/my-app.js:30:28)
    ...
    

    由于它不是真正的用户友好,我想抛出一个 Error 指定一些用户友好的消息(例如“您的配置文件格式不正确”),但我希望保留堆栈跟踪以指向有问题的行。

    在我使用的Java世界中 throw new Exception("My user friendly message", catchedException) 以便具有导致该异常的原始异常。

    如何在JS世界中实现?

    5 回复  |  直到 11 年前
        1
  •  38
  •   Anthony O.    9 年前

    我最后做的是:

    try {
        this.config = JSON.parse(fs.readFileSync(path));
    } catch(err) {
        var newErr = new Error('Problem while reading the JSON file');
        newErr.stack += '\nCaused by: '+err.stack;
        throw newErr;
    }
    
        2
  •  9
  •   Sebastien Lorber    4 年前

    ECMAScript有一个新的错误原因建议,它在TC34达到了第4阶段!

    这意味着它将出现在下一个ECMAScript版本中!

    https://github.com/tc39/proposal-error-cause

    您可以将原因作为错误选项提供:

    throw new Error(`Couldn't parse file at path ${filePath}`, { cause: err });
    

    ES提案仅在语言层面上对其进行形式化,但浏览器/NodeJS通常应同意在实践中记录完整的因果链(参见 https://github.com/nodejs/node/issues/38725 )


    截至今天(2021年底),Firefox Devtools已经能够记录嵌套堆栈跟踪!

    enter image description here

        3
  •  4
  •   eliocs    9 年前

    Joyent发布了一个Node.js包,正好可以用于此目的。它被称为 VError .我粘贴了一个如何使用pacakge的示例:

    var fs = require('fs');
    var filename = '/nonexistent';
    fs.stat(filename, function (err1) {
        var err2 = new VError(err1, 'stat "%s"', filename);
        console.error(err2.message);
    });
    

    将打印以下内容:

    stat "/nonexistent": ENOENT, stat '/nonexistent'
    
        4
  •  0
  •   Erin    5 年前

    2021更新:链接JS中的异常:

    class MyAppError extends Error {
        constructor(...params) {
            super(...params)
            if (Error.captureStackTrace) {
                // This is the key line!
                Error.captureStackTrace(this, this.constructor);
            }
            this.name = this.constructor.name
        }
    }
    

    查看Mozilla文档 Error.captureStackTrace

        5
  •  -4
  •   Moob    11 年前

    使用 try / catch 块:

    try {
        this.config = JSON.parse("}}junkJSON}");
        //...etc
    }
    catch (e) {
        //console.log(e.message);//the original error message 
        e.message = "Your config file is not well formatted.";//replace with new custom message
        console.error(e);//raise the exception in the console
        //or re-throw it without catching
        throw e;
    }
    

    http://jsfiddle.net/0ogf1jxs/5/

    更新: 如果您确实需要自定义错误,您可以定义自己的错误:

    function BadConfig(message) {
       this.message = message;
       this.name = "BadConfig";
    }
    BadConfig.prototype = new Error();
    BadConfig.prototype.constructor = BadConfig;
    
    try {
        this.config = JSON.parse("}}badJson}");
    } catch(e) {
        throw new BadConfig("Your JSON is wack!");
    }
    

    http://jsfiddle.net/kL394boo/

    上有很多有用的信息 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error