招摇工具错误处理程序中间件未捕获错误

Posted

技术标签:

【中文标题】招摇工具错误处理程序中间件未捕获错误【英文标题】:swagger tools error handler middleware not catching errors 【发布时间】:2016-12-03 11:42:22 【问题描述】:

概述

我的自定义 errorHandler 中间件未捕获 swagger-tools 请求验证器错误。相反,swagger 工具的 html 错误被发送回客户端。如何让我的 errorHandler 中间件捕获 swagger 工具验证错误并相应地响应客户端?

我的预后

不幸的是,我一无所知。无论我将 app.use(errorHandler) 指令放在哪里,都会将 swagger 工具 html 错误返回给客户端,并且我的 errorHandler 函数永远不会捕获错误。

也许我忽略了我的设置明显不正确的地方。下面是我的 app.js 文件,在我的 app.js 下面是返回给客户端的 [undesired] swagger-tools HTML 错误响应。同样,我尝试将 app.use(errorHandler) 从字面上(形象地)放在任何地方,尽管下面的代码只在两个地方显示它。

app.js

"use strict";

var swaggerTools = require("swagger-tools");
var compression = require("compression");
var app = require("express")();
var logger = require("./config/logger");
var projectConfig = require("./config/projectConfig");
var debug = require("debug")("app-js"); // run this to enable debug logging DEBUG=app-js node app.js

// swaggerRouter configuration
var options = 
    controllers: './api/controllers',
    useStubs: false
;

// The Swagger document (require it, build it programmatically, fetch it from a URL, ...)
var swaggerDoc = require('./api/swagger/swagger.json');

// compress all requests except those which have Cache-Control header with the no-transform directive
app.use(compression());

// for testing
module.exports = app;

// global error handler
function errorHandler(err, req, res, next, statusCode) 
    logger.error(err);
    debug(err);
    if (res.headersSent) 
        return next(err);
     else 
        res.status(statusCode || 500).json(projectConfig.genericErrorResponse(statusCode || 500, err.message || err || "something blew up and the err object was undefined"));
    


// handles timed out requests
function haltOnTimedout(req, res, next) 
    if (!req.timedout) 
        next();
     else 
        debug("\nrequest timed out!\n");
        next("the request timed out", null, null, null, 504);
    


// Initialize the Swagger middleware
swaggerTools.initializeMiddleware(swaggerDoc, function (middleware) 
    "use strict"

    // Interpret Swagger resources and attach metadata to request - must be first in swagger-tools middleware chain
    app.use(middleware.swaggerMetadata());

    app.use(function (req, res, next) 
        res.header("Access-Control-Allow-Origin", "*"); // CORS should be parametrized by configuration
        res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
        next();
    );

    // Validate Swagger requests
    // app.use(middleware.swaggerValidator());

    app.use(middleware.swaggerValidator(
        validateResponse: false
    ));

    app.use(haltOnTimedout);
    app.use(errorHandler);

    // Route validated requests to appropriate controller
    app.use(middleware.swaggerRouter(options));
);

app.use(haltOnTimedout);
app.use(errorHandler);

app.listen(projectConfig.port || process.env.PORT || 9000)
    .on("connection", function (socket) 
        debug("\na new cxn was made by a client.\n");
        socket.setTimeout(projectConfig.expressTimeout || 120000);
    )

swagger 工具 html 错误返回给客户端

Error: Parameter (copy) failed schema validation
<br> &nbsp; &nbsp;at throwErrorWithCode (/Users/cuv/Documents/dev/dev-project/dev-simple/node_modules/swagger-tools/lib/validators.js:121:13)
<br> &nbsp; &nbsp;at Object.module.exports.validateAgainstSchema (/Users/cuv/Documents/dev/dev-project/dev-simple/node_modules/swagger-tools/lib/validators.js:176:7)
<br> &nbsp; &nbsp;at /Users/cuv/Documents/dev/dev-project/dev-simple/node_modules/swagger-tools/middleware/swagger-validator.js:143:22
<br> &nbsp; &nbsp;at /Users/cuv/Documents/dev/dev-project/dev-simple/node_modules/async/lib/async.js:356:13
<br> &nbsp; &nbsp;at async.forEachOf.async.eachOf (/Users/cuv/Documents/dev/dev-project/dev-simple/node_modules/async/lib/async.js:233:13)
<br> &nbsp; &nbsp;at _asyncMap (/Users/cuv/Documents/dev/dev-project/dev-simple/node_modules/async/lib/async.js:355:9)
<br> &nbsp; &nbsp;at Object.map (/Users/cuv/Documents/dev/dev-project/dev-simple/node_modules/async/lib/async.js:337:20)
<br> &nbsp; &nbsp;at validateValue (/Users/cuv/Documents/dev/dev-project/dev-simple/node_modules/swagger-tools/middleware/swagger-validator.js:136:11)
<br> &nbsp; &nbsp;at /Users/cuv/Documents/dev/dev-project/dev-simple/node_modules/swagger-tools/middleware/swagger-validator.js:343:21
<br> &nbsp; &nbsp;at /Users/cuv/Documents/dev/dev-project/dev-simple/node_modules/async/lib/async.js:356:13

我运行的是什么版本?

节点:

node --version
v6.2.2

swagger-tools 和 express 的最新版本:

"swagger-tools": "^0.10.1",
"express": "^4.12.3"

关闭

任何关于如何让我的 errorHandler 中间件捕获并因此覆盖 swagger-tools html 错误的帮助和/或洞察力将非常有用。我也在 apigee 社区论坛中发布了我的问题,因为它是 apigee-127 项目的一部分。 https://community.apigee.com/questions/29267/swagger-tools-error-handler-middleware-not-catchin.html

谢谢!

【问题讨论】:

【参考方案1】:

我发现了两个问题。

首先:错误处理程序必须有 4 个参数,因此 statusCode 将被忽略。

errorHandler(err, req, res, next) // correct definition

第二名是

next("the request timed out", null, null, null, 504);

错误句柄的第一个参数必须是错误对象而不是字符串,所以正确的代码将是

next(new Error("the request timed out")); // other args passed by closure

通过statusCode的方式有很多种。

// 1. Bad way: Pass string with delimiter
next(new Error("the request timed out;404"));
...
// In error handler
var args = err.message.split() // => args[0] = the request timed out, args[1] = 404

// 2. Check message error text
If (err.message == 'the request timed out')  
    statusCode = 404;

// 3. Best way is use custom error

更多关于自定义错误here

【讨论】:

进行您提到的前两个更改解决了问题!我正在增强我的错误处理机制,以更符合您在链接中引用的内容。谢谢艾康!

以上是关于招摇工具错误处理程序中间件未捕获错误的主要内容,如果未能解决你的问题,请参考以下文章

捕获 async-await 快速路由处理程序中的所有错误

iOS异常信号的捕获和简单处理

快速错误处理和异步等待

未捕获的类型错误:无法通过淘汰处理绑定“if”

如何在 Perl 子例程中处理已捕获和未捕获的错误?

当我创建一个函数来处理我的 xhrhttp 请求时,如何解决未捕获的类型错误?