首页 > 解决方案 > 使用 Got 允许在特定条件下重试 HTTP 请求

问题描述

我在我的应用程序中使用Got库来处理 HTTP 请求。我正在向 API 发出 HTTP 请求,在某些条件下我可以期望 HTTP 代码 404。我想使用 Got 的内部重试功能重新运行请求,直到 404 错误消失(这会发生;我只是不知道需要 1 分钟还是 30 分钟)。

从文档中我知道 HTTP 代码 404 不是内置重试功能支持的状态代码,因此我无法在 Got 的 beforeRetry 钩子中执行任何操作;看这里

我正在扩展一个 Got 实例,以允许对我正在调用的 API 进行一些预设。目前我还没有找到一种干净的方法来扩展现有的重试状态码 404。

const gitlabOnPrem = got.extend({
    prefixUrl: ".." + "..",
    mutableDefaults: true,
    responseType: 'json',
    //retry: { statusCode: got.defaults.options.retry.statusCode.push(404) }, //does not work | not clean
    https: { rejectUnauthorized: false },
    headers: {
        'PRIVATE-TOKEN': "..",
        Accept: 'application/json',
    },
    hooks: {
        beforeError: [
            (error) => {
                const { response } = error;
                console.log(response);
                /*
                Another idea: if I cannot extend retry statusCodes then I´d like to somehow force a retry from here
                if (response.statusCode === 404 && response.path.endsWith('/export/download')) {
                    console.log('FORCE A RETRY AS THE DOWNLOAD MIGHT NOT BE READY YET');
                }
                */

                if (response && response.body) {
                    error.name = 'GitLabOnPremError';
                    error.message = `${response.body.message !== undefined
                            ? response.body.message
                            : response.body.error
                        } (${response.statusCode})`;
                }

                return error;
            },
        ],
    },
});
  1. 如何扩展允许运行重试的 HTTP 状态代码?
  2. 如果这不可能,请参阅我在代码中的评论。是否有可能仅使用 Got 手动强制重试?

标签: javascriptnode.jshttprequest

解决方案


有时最好自己写。试图让一个库以一种并非完全按照它的方式工作可能比它的价值更痛苦。从长远来看,它通常也很脆弱。

为什么不自己包装呢?像这样的东西:

async function MyGotFn() {

    let retries = 100;
    let statusCode = 404;
    let response;

    while (statusCode === 404 && --retries > 0) {
        response = await got('...');
        statusCode = response.statusCode;
    }

    if (response.statusCode === 404) throw new Error('max retries reached');

    return response;
}


推荐阅读