From 107664ab220dc389c6dbb9c0f85a20cf0ba1ed3d Mon Sep 17 00:00:00 2001 From: MzUgM <108896003+MzUgM@users.noreply.github.com> Date: Mon, 4 Dec 2023 21:57:56 +0000 Subject: [PATCH] Expose HTTP errors that are not meant to be retried (#2496) * test: failing test to show http response not passed through * fix: pass through requests that do not expect a retry * refactor: cleanup --- lib/handler/RetryHandler.js | 23 +++++++++---- test/retry-handler.js | 69 +++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 7 deletions(-) diff --git a/lib/handler/RetryHandler.js b/lib/handler/RetryHandler.js index 371044719fd..da35d256baa 100644 --- a/lib/handler/RetryHandler.js +++ b/lib/handler/RetryHandler.js @@ -172,13 +172,22 @@ class RetryHandler { this.retryCount += 1 if (statusCode >= 300) { - this.abort( - new RequestRetryError('Request failed', statusCode, { - headers, - count: this.retryCount - }) - ) - return false + if (this.retryOpts.statusCodes.includes(statusCode) === false) { + return this.handler.onHeaders( + statusCode, + rawHeaders, + resume, + statusMessage + ) + } else { + this.abort( + new RequestRetryError('Request failed', statusCode, { + headers, + count: this.retryCount + }) + ) + return false + } } // Checkpoint for resume from where we left it diff --git a/test/retry-handler.js b/test/retry-handler.js index a4577a6a3e1..d90ff5ebc45 100644 --- a/test/retry-handler.js +++ b/test/retry-handler.js @@ -620,3 +620,72 @@ tap.test('retrying a request with a body', t => { ) }) }) + +tap.test('should not error if request is not meant to be retried', t => { + const server = createServer() + server.on('request', (req, res) => { + res.writeHead(400) + res.end('Bad request') + }) + + t.plan(3) + + const dispatchOptions = { + retryOptions: { + method: 'GET', + path: '/', + headers: { + 'content-type': 'application/json' + } + } + } + + server.listen(0, () => { + const client = new Client(`http://localhost:${server.address().port}`) + const chunks = [] + const handler = new RetryHandler(dispatchOptions, { + dispatch: client.dispatch.bind(client), + handler: { + onConnect () { + t.pass() + }, + onBodySent () { + t.pass() + }, + onHeaders (status, _rawHeaders, resume, _statusMessage) { + t.equal(status, 400) + return true + }, + onData (chunk) { + chunks.push(chunk) + return true + }, + onComplete () { + t.equal(Buffer.concat(chunks).toString('utf-8'), 'Bad request') + }, + onError (err) { + console.log({ err }) + t.fail() + } + } + }) + + t.teardown(async () => { + await client.close() + server.close() + + await once(server, 'close') + }) + + client.dispatch( + { + method: 'GET', + path: '/', + headers: { + 'content-type': 'application/json' + } + }, + handler + ) + }) +})