【问题标题】:NodeJS Error EncapsulationNodeJS 错误封装
【发布时间】:2016-09-24 10:50:12
【问题描述】:

我目前正在尝试处理 NodeJS 应用程序中的异常和错误,这些应用程序将用于关键信息。我需要一个干净的错误管理! 我一直想知道是否有类似Java Exceptions 封装的东西。

我在解释。

在 Java 中你可以做类似的事情:

try {
    // something that throws Exception
} catch (Throwable t) {
    throw new Exception("My message", t);
}

这使您可以决定何时记录您的异常并获得整个堆栈跟踪和调用路径!

我想知道是否有办法在 NodeJS 中做同样的事情,因为在每一步都记录似乎不是正确的做事方式。

谢谢。

【问题讨论】:

    标签: node.js error-handling encapsulation propagation


    【解决方案1】:

    你应该看看这个模块: https://www.npmjs.com/package/verror

    Joyent 在他的错误管理最佳实践中引用它:https://www.joyent.com/developers/node/design/errors

    在 Joyent,我们使用 verror 模块来包装错误,因为它是 语法简洁。在撰写本文时,它并没有完全做到 这还没有,但它会扩展到这样做。

    它允许您获取有关错误消息的详细信息。并跟踪错误的步骤。

    并且还通过包装的错误向客户端隐藏详细信息:WError() 仅返回最后一条错误消息。

    【讨论】:

    • 谢谢,我去看看!
    • 这就是我一直在寻找的东西,但为什么它不是原生的?!无论如何,谢谢!
    • 那个库不错,但已经完成了一半。当您将先前的错误 A 封装到错误 B 中时。最终消息是正确的,但堆栈跟踪仅是 B :'(
    【解决方案2】:

    我回答我自己的问题来解释我最终做了什么来获得想要的封装。 我按照 Sachacr 的建议使用了 https://www.npmjs.com/package/verror

    然后我以这种方式扩展它:

    my_error.js:

    var VError          = require('verror');
    var _               = require('lodash');
    
    function MyError() {
        var args = [];
    
        var httpErrorCode;
        var cause;
    
        if (arguments.length > 0) {
            var lastArgumentIndex = [arguments.length];
    
            cause = manageCause(lastArgumentIndex, arguments);
            httpErrorCode = manageHttpCode(lastArgumentIndex, arguments);
    
            for (var i = 0; i < lastArgumentIndex; i++) {
                args[i] = arguments[i];
            }
        }
    
        this.__proto__.__proto__.constructor.apply(this, args);
    
        if (cause) {
            if (this.stack) {
                this.stack += '\n' + cause.stack;
            } else {
                this.stack = cause.stack;
            }
        }
    
        this.httpErrorCode = httpErrorCode;
    }
    
    MyError.prototype.__proto__ = VError.prototype;
    
    function manageCause(lastArgumentIndex, arguments) {
        if (lastArgumentIndex[0] > 0
            && arguments[lastArgumentIndex[0] - 1] instanceof Error) {
    
            lastArgumentIndex[0]--;
            return arguments[lastArgumentIndex[0]];
        }
    }
    
    function manageHttpCode(lastArgumentIndex, arguments) {
        if (lastArgumentIndex[0] > 0
            && _.isNumber(arguments[lastArgumentIndex[0] - 1])) {
    
            lastArgumentIndex[0]--;
            return arguments[lastArgumentIndex[0]];
        }
    }
    
    module.exports = MyError;
    

    它让我可以在我的代码中轻松使用它:

    var MyError = require('./my_error.js');
    
    function withErrors() {
        try {
            // something with errors
        } catch (err) {
            // This is the same pattern as VError
            return new MyError("My message", err, 401);
        }
    }
    
    function somethingToDo(req, res) {
        var result = withErrors();
    
        if (result instanceof MyError) {
            logger.warn(result);
            res.status(result.httpErrorCode).send(result.message).end();
            return
        }
    }
    

    这样,我有一个很好的堆栈跟踪,其中包含调用路径和涉及错误/异常的每一行。

    希望它能帮助人们,因为我搜索了很长时间:)

    编辑:我修改了 MyError 类以添加 HTTP 错误代码和清理参数管理。

    【讨论】:

      【解决方案3】:

      您应该能够执行以下操作:

      funtion exception(message, error) {
          this.message = message;
          this.stacktrace = error.stack;
      }
      
      try {
         if(someData == false)
            throw new exception("something went wrong!", new Error());
      }
      catch(ex) {
          console.log(ex.message);
          console.log(ex.stacktrace);
      }
      

      然后您可以抛出您自己的自定义异常实例,其中包含您需要的任何调试信息。

      编辑:向异常对象添加堆栈跟踪

      【讨论】:

      • 重点是我不想马上记录下来。我希望我的调用函数能够获取该错误并对其进行管理(可能是记录它,可能是抛出它,...)。因为如果我现在记录它,我不知道整个上下文。所以我想在不丢失任何信息的情况下进行宣传。
      • 所以没有本地方法来正确处理错误传播?我必须创建自己的结构吗?
      • NodeJS 只是 chromium 的 javascript 引擎,有一些花里胡哨。除非有可用的节点包,否则我目前不知道任何原生方式。
      猜你喜欢
      • 2018-04-26
      • 1970-01-01
      • 2015-02-24
      • 1970-01-01
      • 2021-10-19
      • 1970-01-01
      • 1970-01-01
      • 2021-05-07
      • 2013-06-05
      相关资源
      最近更新 更多