阻止HTTP 503响应拒绝承诺

时间:2017-03-06 11:38:34

标签: node.js promise http-error

这可能听起来像滥用Promises,但这是我的用例。

我正在编写基于NodeJS的工具来验证存储在OAS(Swagger)文件中的API定义。这项任务的一部分涉及检查通过连接"主机"而构建的端点的有效性。和" basepath"具有每个端点名称的属性"路径"属性。

我正在使用NodeJS库'承诺'包装标准的请求'使用此行的库



var request = require('request')
var Promise = require('promise')

// Wrap the HTTP HEAD request in a promise
request.head = Promise.denodeify(request.head)




我正在使用HTTP HEAD请求,因为我对实际调用API不感兴趣 - 我只是想确保OAS文件中显示的URL指向有效的目标。

这意味着几乎所有响应状态代码都是可接受的,除了404(未找到)和410(已完成)。

但是,如果出现HTTP 503(服务不可用)响应,请求' NodeJS库将此报告为错误,然后导致Promise包装request.head()调用被拒绝。

由于API的实现方式存在很大差异,如果位于我检查的URL后面的API管理层想要显式阻止HTTP HEAD请求,那么它可能会通过HTTP 503响应来实现比预期更多的HTTP 405(方法不允许)。此外,如果API已经沙箱化,则HTTP 503是预期的状态代码。

无论哪种方式,HTTP 503都证明这个URL实际上是有效的,即使我使用可能不允许的HTTP方法调用它。

我认为"反驳" Promise是一种滥用(也可能也是不可能的),因此我可能不得不自己处理HTTP请求,这样503就不会被视为错误。

任何人都有更好的主意吗?

由于

Chris W

1 个答案:

答案 0 :(得分:0)

  

我认为“拒绝”承诺是滥用(也可能是不可能的),

“Unrejecting”承诺确实是不可能的。更改状态的唯一方法是使用.then().catch()形成一个promise链,并从回调中进行适当的返回(或抛出)。

  

因此我不得不自己处理HTTP请求,以免503被视为错误。

这可能是未来最现实的方式,即request.head()的定制手动宣传。

问题表明坏代码列表很短(404和410),因此只有在遇到这些代码时才更容易拒绝。

function testUrl(url) {
    const badCodes = [404, 410];
    return new Promise((resolve, reject) => {
        request.head(url, (error, response, body) => {
            if(error) {
                if(response && badCodes.indexOf(+response.statusCode) === -1) {
                    resolve(response.statusCode);
                } else {
                    reject error;
                }
            } else {
                resolve(response.statusCode);
            }
        });
    });
}

或者,如果您要接受的错误代码列表很短,那么测试逻辑很容易被反转。

function testUrl(url) {
    const goodCodes = [503];
    return new Promise((resolve, reject) => {
        request.head(url, (error, response, body) => {
            if(error) {
                if(response && goodCodes.indexOf(+response.statusCode) > -1) {
                    resolve(response.statusCode);
                } else {
                    reject(error);
                }
            } else {
                resolve(response.statusCode);
            }
        });
    });
}

您可以使用逻辑来获得您想要的内容。

无论你最终如何,请致电:

testUrl('http://path/to/resource').then(function(statusCode) {
    // pass
}, function(error) {
    // fail
});