防止 Sails.js 处理错误

Prevent Sails.js from handling errors

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

当我在 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 项目的任何错误?

提前致谢!

您发布的代码将完全按照其说明进行操作:处理 未捕获 异常。 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!)

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

Sails 是一个 Web Framework 将您的代码包装到 web 应用程序中,因此它不可能永不停机,因此-Sails 尝试自行处理所有错误,并在以下情况下用 500 通知用户需要,并继续 运行 网络应用程序。

Sails 应用分为 2 个步骤:

  1. 提升之前-任何人都无法访问 Web 应用程序:

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

  2. 提升后-Web应用可访问:

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

如果 Sails 在 运行 网络应用程序(提升后)时出现异常,有 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 函数命中,所以我们可以在那里对错误做任何我们想做的事情,例如。登录到文件,登录到日志管理工具,发送邮件给管理员等