【问题标题】:Prevent Sails.js from handling errors防止 Sails.js 处理错误
【发布时间】:2016-02-11 10:56:26
【问题描述】:

我有一个运行 Sails.js (v0.12.0) 的 Node.js (v5.6.0, npm: v3.7.1) 应用程序。

当我在app.js中执行这段代码时:

process.on('uncaughtException', err => {
  //Do something
});
throw new Error();

它处理我的错误。

问题是,在我加载 Sails 后,我根本无法使用此方法捕获错误。 例如,从bootstrap.js 抛出错误不会被上述代码捕获,我在控制台中收到此消息:

error: Bootstrap encountered an error: (see below)
error: Error: asdf
    at Object.module.exports.bootstrap.process.on.process.on.process.on.sails.async.series.callback [as bootstrap] 
    (c:\path\to\project\config\bootstrap
    .js:41:8)
    at Sails.runBootstrap (c:\path\to\project\node_modules\sails\lib\app\private\bootstrap.js:44:25)
    at Sails.wrapper [as runBootstrap] (c:\path\to\project\node_modules\sails\node_modules\lodash\index.js:3095:19)
    at Sails.initialize (c:\path\to\project\node_modules\sails\lib\app\private\initialize.js:54:9)
    at wrapper (c:\path\to\project\node_modules\sails\node_modules\lodash\index.js:3095:19)
    at c:\path\to\project\node_modules\sails\node_modules\async\lib\async.js:713:13
    at iterate (c:\path\to\project\node_modules\sails\node_modules\async\lib\async.js:262:13)
    at c:\path\to\project\node_modules\sails\node_modules\async\lib\async.js:274:29
    at c:\path\to\project\node_modules\sails\node_modules\async\lib\async.js:44:16
    at c:\path\to\project\node_modules\sails\node_modules\async\lib\async.js:718:17
    at c:\path\to\project\node_modules\sails\node_modules\async\lib\async.js:167:37
    at module.exports (c:\path\to\project\node_modules\sails\lib\app\load.js:184:13)
    at _toString (c:\path\to\project\node_modules\sails\node_modules\async\lib\async.js:52:16)
    at c:\path\to\project\node_modules\sails\node_modules\async\lib\async.js:548:17
    at c:\path\to\project\node_modules\sails\node_modules\async\lib\async.js:542:17
    at _arrayEach (c:\path\to\project\node_modules\sails\node_modules\async\lib\async.js:85:13) [Error: asdf]

我也尝试将上面的代码移动到bootstrap.js,但没有任何运气。

如何处理 Sails 项目的任何错误?

提前致谢!

【问题讨论】:

    标签: node.js error-handling sails.js bootstrapping uncaught-exception


    【解决方案1】:

    对于谁会来这里寻找完整代码,我发布了我的完整代码和解释,基于 @sgress454 答案:

    Sails 是一个Web Framework,它将您的代码包装到 Web 应用程序中,因此它永远不会关闭,因此 - Sails 尝试自行处理所有错误,并在需要时以 500 通知用户,然后继续运行 Web 应用程序。

    Sails 应用分为 2 个步骤:

    1. 吊装前 - 任何人都无法访问 Web 应用程序:

      如果 Sails 出现异常,它将退出应用程序,并使用 error 参数调用提升回调。

    2. Lifting-Web应用程序可访问:

      如果 Sails 出现异常,它将退出应用程序,并使用 error 参数调用提升回调。

    如果 Sails 在运行 Web 应用程序时出现异常(提升后),有 2 个选项:

    1. 控制器动作本身内部的异常:

      Sails 将捕获此错误,并以 500 响应用户。

    2. 其他地方例外:

      Sails 不会捕捉到这个错误,并且会抛出 uncaughtException

    要处理上述所有情况,我们需要执行以下操作:

    首先我们要创建一个全局函数,以便我们可以从代码中的任何位置调用它:

    ES 2015:

    //app.js
    global.handleErrors = err => {
        //do something
    }
    

    ES 5.1(及之前):

    //app.js
    global.handleErrors = function(err) {
        //do something
    }
    

    现在我们要处理uncaughtException 的所有事件:

    //app.js
    process.on('uncaughtException', handleErrors);
    

    我们可以添加一些其他事件,例如:

    //app.js
    process.on('unhandledRejection', handleErrors);
    process.on('rejectionHandled', handleErrors);
    process.on('SIGINT', handleErrors);
    

    为了捕捉提升过程中发生的异常,我们需要为sails.lift函数提供回调,如果使用error调用回调,我们需要调用我们创建的handleErrors函数:

    ES 2015:

    //app.js
    sails.lift(rc('sails'), err => {
        if (err) {
            handleErrors(err);
        }
    });
    

    ES 5.1(及之前):

    //app.js
    sails.lift(rc('sails'), function(err) {
        if (err) {
            handleErrors(err);
        }
    });
    

    我们希望在控制器中处理 Sails 捕获并以 500 响应的异常:

    //api/responses/serverError.js
    module.exports = function serverError(data, options) {
        handleErrors(data);
        //lot of Sails things
    };
    

    通过这种方式,所有的错误最终都会被handleErrors 函数击中,所以我们可以在那里做任何我们想做的错误,例如。登录到文件、登录到日志管理工具、向管理员发送电子邮件等。

    【讨论】:

      【解决方案2】:

      您发布的代码将完全按照它所说的执行:处理 未捕获 异常。 Sails 处理初始化期间发生的错误,因此它可以尝试优雅地退出,并尝试处理处理请求时发生的错误,以便它可以优雅地响应(带有错误页面)而不是使服务器崩溃。

      要处理初始化过程中发生的错误,请在app.js 文件中向.lift() 提供第二个参数——错误处理函数:

      sails.lift(rc('sails'), function handleLiftError(err, sailsInstance) {
         if (err) {
            console.log("Error occurred during sails.lift: ", err);
         }
      });
      

      您仍然可以保留 process.on('uncaughtException'),... 代码来处理应用运行时弹出的致命错误。例如,如果您在控制器操作中有以下内容:

      myAction: function (req, res) {
        throw new Error('foo!);
      }
      

      然后 Sails 会为您捕获该错误,并返回 500 错误页面。但如果你有:

      myAction: function (req, res) {
        setTimeout(function(){throw new Error('foo!);}
      }
      

      Sails 根本无法捕捉到它——但您的 process.on 处理程序会(前提是您使用 node app.js 启动 Sails!)

      【讨论】:

      • 非常感谢!它很棒而且很有效。我最终做了什么:在app.js中我写了:global.handleErrors = err => {/*do something*/};,然后在err发生在sails.lift中时调用它,并且我在api/responses/serverError.js中添加了对该函数的调用以处理错误已直接从控制器抛出。
      • @Ziki,你能分享你的代码吗?我也遇到了这个问题。
      猜你喜欢
      • 2014-04-09
      • 2012-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-05
      • 2014-11-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多