diff --git a/test/fixtures/interceptors/retry-event-loop.js b/test/fixtures/interceptors/retry-event-loop.js new file mode 100644 index 00000000000..0a92d0d27a6 --- /dev/null +++ b/test/fixtures/interceptors/retry-event-loop.js @@ -0,0 +1,33 @@ +'use strict' + +const { createServer } = require('node:http') +const { once } = require('node:events') +const { + Client, + interceptors: { retry } +} = require('../../..') + +const server = createServer() + +server.on('request', (req, res) => { + res.writeHead(418, { 'Content-Type': 'text/plain' }) + res.end('teapot') +}) + +server.listen(0) +once(server, 'listening').then(() => { + const client = new Client( + `http://localhost:${server.address().port}` + ).compose( + retry({ + maxTimeout: 1000, + maxRetries: 3, + statusCodes: [418] + }) + ) + + return client.request({ + method: 'GET', + path: '/' + }) +}) diff --git a/test/interceptors/retry.js b/test/interceptors/retry.js index df75a636b8b..346270e747a 100644 --- a/test/interceptors/retry.js +++ b/test/interceptors/retry.js @@ -4,6 +4,7 @@ const { tspl } = require('@matteo.collina/tspl') const { test, after } = require('node:test') const { createServer } = require('node:http') const { once } = require('node:events') +const { spawnSync } = require('node:child_process') const { Client, interceptors } = require('../..') const { retry, redirect, dns } = interceptors @@ -559,3 +560,16 @@ test('should not error if request is not meant to be retried', async t => { t.equal(response.statusCode, 400) t.equal(await response.body.text(), 'Bad request') }) + +test('#3975 - keep event loop ticking', async t => { + const suite = tspl(t, { plan: 3 }) + + const res = spawnSync('node', ['./test/fixtures/interceptors/retry-event-loop.js'], { + stdio: 'pipe' + }) + + const output = res.stderr.toString() + suite.ok(output.includes("code: 'UND_ERR_REQ_RETRY'")) + suite.ok(output.includes('RequestRetryError: Request failed')) + suite.ok(output.includes('statusCode: 418')) +})