为什么以下代码在非正常HTTP代码的情况下抛出Promise?

时间:2018-06-04 16:04:42

标签: javascript promise fetch-api

我编写了下面的代码,试图优雅地处理连接错误和不正常的HTTP状态代码,以及在某些情况下重试。

出于某种原因,我无法通过阅读代码来推断,在HTTP状态代码错误的情况下,Promise作为参数传递给赋予catch函数 (我知道'catch()`本身会返回一个Promise)。即

testGet(500).catch(res => console.log(res))

将打印[object Promise]

有谁能告诉我在下面的代码中我在哪里抛出一个Promise对象?或者,换句话说,为什么handleStatusError返回一个Promise,当它看起来给出一个Response(它返回)?

// **** Behavior ****
// 
// HTTP error 4xx:   Don't retry (we messed up)
// HTTP error 5xx:   Retry (the server messed up)
// Connection error: Retry (ITU's wifi messed up)

export function testGet(code) {
    var url = "http://httpstat.us/" + code
    console.log("Fetching '" + url + "'")
    return httpGet(url, 2);
}

export function httpGet(url, numRetries) { 
    var options = { 
        mode: 'cors',
        headers: {
            'Accept':       'application/json',
          }
    };
    return fetchRetry(url, options, numRetries);
}

export function httpPost(url, body, numRetries) { 
    var options = {
        method: 'POST',
        headers: {
          'Accept':       'application/json',
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(body),
    };
    return fetchRetry(url, options, numRetries); 
}

function fetchRetry(url, options, numRetries) {
    numRetries = numRetries || 1;
    return httpRequest(url, options).catch(error => {
        if (numRetries <= 1 || error.retry !== true) {
            throw error.json();
        } else {
            return fetchRetry(url, options, numRetries - 1);
        }
    });
}

function httpRequest(url, options) {
    return fetch(url, options)
        // Handle connection/network error
        .catch(error => { 
            error.retry = true;
            error.json = () => error.message || "Network/connection error";
            throw error;
        })
        .then(response => { 
            if (response.ok) return response.json();
            // Handle HTTP status code error
            else throw handleStatusError(response);
        });
}

const handleStatusError = response => {
    response.retry = false;
    // Check status code
    var status = response.status;
    if (status >= 400 && status < 500) {        // User error
        response.retry = false;
    } else if (status >= 500 && status < 600) { // Server error
        response.retry = true;
    }
    return response;
}

0 个答案:

没有答案