feat(rest): callbacks for timeout and retry backoff (#11067)

* feat(rest): callbacks for timeout and retry backoff

* test: add tests for callback utils

* test: fix typo

Co-authored-by: Qjuh <76154676+Qjuh@users.noreply.github.com>

* fix(retryBackoff): efficient math

* docs: minor tweaks

* docs: captalisation

---------

Co-authored-by: Qjuh <76154676+Qjuh@users.noreply.github.com>
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
This commit is contained in:
ckohen
2025-09-10 02:23:28 -07:00
committed by GitHub
parent 5d5a6945e4
commit f1bcff46b6
8 changed files with 263 additions and 6 deletions

View File

@@ -16,6 +16,7 @@ const api = new REST();
let mockAgent: MockAgent;
let mockPool: Interceptable;
let serverOutage = true;
beforeEach(() => {
mockAgent = new MockAgent();
@@ -138,3 +139,57 @@ test('Handle unexpected 429', async () => {
expect(await unexpectedLimit).toStrictEqual({ test: true });
expect(performance.now()).toBeGreaterThanOrEqual(previous + 1_000);
});
test('server responding too slow', async () => {
const api2 = new REST({ timeout: 1 }).setToken('A-Very-Really-Real-Token');
api2.setAgent(mockAgent);
mockPool
.intercept({
path: callbackPath,
method: 'POST',
})
.reply(200, '')
.delay(100)
.times(10);
const promise = api2.post('/interactions/1234567890123456789/totallyarealtoken/callback', {
auth: false,
body: { type: 4, data: { content: 'Reply' } },
});
await expect(promise).rejects.toThrowError('aborted');
}, 1_000);
test('Handle temp server outage', async () => {
mockPool
.intercept({
path: callbackPath,
method: 'POST',
})
.reply(() => {
if (serverOutage) {
serverOutage = false;
return {
statusCode: 500,
data: '',
};
}
return {
statusCode: 200,
data: { test: true },
responseOptions,
};
})
.times(2);
expect(
await api.post('/interactions/1234567890123456789/totallyarealtoken/callback', {
auth: false,
body: { type: 4, data: { content: 'Reply' } },
}),
).toStrictEqual({ test: true });
});