Skip to content

Commit ef276d4

Browse files
fgiovametcoder95
andauthored
fix: Fix retry-handler.js when retry-after header is a Date (#4084)
Co-authored-by: Carlos Fuentes <[email protected]>
1 parent 6179788 commit ef276d4

File tree

3 files changed

+95
-9
lines changed

3 files changed

+95
-9
lines changed

lib/handler/retry-handler.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ const {
1111
} = require('../core/util')
1212

1313
function calculateRetryAfterHeader (retryAfter) {
14-
const current = Date.now()
15-
return new Date(retryAfter).getTime() - current
14+
const retryTime = new Date(retryAfter).getTime()
15+
return isNaN(retryTime) ? 0 : retryTime - Date.now()
1616
}
1717

1818
class RetryHandler {
@@ -124,7 +124,7 @@ class RetryHandler {
124124
if (retryAfterHeader) {
125125
retryAfterHeader = Number(retryAfterHeader)
126126
retryAfterHeader = Number.isNaN(retryAfterHeader)
127-
? calculateRetryAfterHeader(retryAfterHeader)
127+
? calculateRetryAfterHeader(headers['retry-after'])
128128
: retryAfterHeader * 1e3 // Retry-After is in seconds
129129
}
130130

test/interceptors/retry.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,19 +191,19 @@ test('Should use retry-after header for retries (date)', async t => {
191191
server.on('request', (req, res) => {
192192
switch (counter) {
193193
case 0:
194+
checkpoint = Date.now()
194195
res.writeHead(429, {
195196
'retry-after': new Date(
196-
new Date().setSeconds(new Date().getSeconds() + 1)
197+
checkpoint + 2000
197198
).toUTCString()
198199
})
199200
res.end('rate limit')
200-
checkpoint = Date.now()
201201
counter++
202202
return
203203
case 1:
204204
res.writeHead(200)
205205
res.end('hello world!')
206-
t.ok(Date.now() - checkpoint >= 1)
206+
t.ok(Date.now() - checkpoint >= 1000)
207207
counter++
208208
return
209209
default:

test/retry-handler.js

Lines changed: 89 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -364,19 +364,19 @@ test('Should use retry-after header for retries (date)', async t => {
364364
server.on('request', (req, res) => {
365365
switch (counter) {
366366
case 0:
367+
checkpoint = Date.now()
367368
res.writeHead(429, {
368369
'retry-after': new Date(
369-
new Date().setSeconds(new Date().getSeconds() + 1)
370+
checkpoint + 2000
370371
).toUTCString()
371372
})
372373
res.end('rate limit')
373-
checkpoint = Date.now()
374374
counter++
375375
return
376376
case 1:
377377
res.writeHead(200)
378378
res.end('hello world!')
379-
t.ok(Date.now() - checkpoint >= 1)
379+
t.ok(Date.now() - checkpoint >= 1000)
380380
counter++
381381
return
382382
default:
@@ -1547,3 +1547,89 @@ test('Should throw RequestRetryError when Content-Range mismatch', async t => {
15471547

15481548
await t.completed
15491549
})
1550+
1551+
test('Should use retry-after header for retries (date) but date format is wrong', async t => {
1552+
t = tspl(t, { plan: 3 })
1553+
1554+
let counter = 0
1555+
const chunks = []
1556+
const server = createServer()
1557+
let checkpoint
1558+
const dispatchOptions = {
1559+
method: 'PUT',
1560+
path: '/',
1561+
headers: {
1562+
'content-type': 'application/json'
1563+
},
1564+
retryOptions: {
1565+
minTimeout: 1000
1566+
}
1567+
}
1568+
1569+
server.on('request', (req, res) => {
1570+
switch (counter) {
1571+
case 0:
1572+
checkpoint = Date.now()
1573+
res.writeHead(429, {
1574+
'retry-after': 'this is not a date'
1575+
})
1576+
res.end('rate limit')
1577+
counter++
1578+
return
1579+
case 1:
1580+
res.writeHead(200)
1581+
res.end('hello world!')
1582+
t.ok(Date.now() - checkpoint >= 1000)
1583+
counter++
1584+
return
1585+
default:
1586+
t.fail('unexpected request')
1587+
}
1588+
})
1589+
1590+
server.listen(0, () => {
1591+
const client = new Client(`http://localhost:${server.address().port}`)
1592+
const handler = new RetryHandler(dispatchOptions, {
1593+
dispatch: client.dispatch.bind(client),
1594+
handler: {
1595+
onConnect () {
1596+
t.ok(true, 'pass')
1597+
},
1598+
onHeaders (status, _rawHeaders, resume, _statusMessage) {
1599+
t.strictEqual(status, 200)
1600+
return true
1601+
},
1602+
onData (chunk) {
1603+
chunks.push(chunk)
1604+
return true
1605+
},
1606+
onComplete () {
1607+
t.strictEqual(Buffer.concat(chunks).toString('utf-8'), 'hello world!')
1608+
},
1609+
onError (err) {
1610+
t.ifError(err)
1611+
}
1612+
}
1613+
})
1614+
1615+
after(async () => {
1616+
await client.close()
1617+
server.close()
1618+
1619+
await once(server, 'close')
1620+
})
1621+
1622+
client.dispatch(
1623+
{
1624+
method: 'PUT',
1625+
path: '/',
1626+
headers: {
1627+
'content-type': 'application/json'
1628+
}
1629+
},
1630+
handler
1631+
)
1632+
})
1633+
1634+
await t.completed
1635+
})

0 commit comments

Comments
 (0)