Skip to content

Commit 85f50c1

Browse files
authored
Add retry wrapper to all discord endpoints (#1857)
1 parent 8f6ac75 commit 85f50c1

8 files changed

Lines changed: 173 additions & 134 deletions

File tree

services/libs/integrations/src/integrations/discord/api/getChannel.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import axios, { AxiosRequestConfig } from 'axios'
22
import { handleDiscordError } from './errorHandler'
33
import { DiscordApiChannel } from '../types'
44
import { IProcessStreamContext } from '../../../types'
5+
import { retryWrapper } from './handleRateLimit'
56

67
export const getChannel = async (
78
channelId: string,
@@ -16,13 +17,15 @@ export const getChannel = async (
1617
},
1718
}
1819

19-
try {
20-
const response = await axios(config)
21-
return response.data
22-
} catch (err) {
23-
const newErr = handleDiscordError(err, config, { channelId }, ctx)
24-
if (newErr) {
25-
throw newErr
20+
return await retryWrapper(3, async () => {
21+
try {
22+
const response = await axios(config)
23+
return response.data
24+
} catch (err) {
25+
const newErr = handleDiscordError(err, config, { channelId }, ctx)
26+
if (newErr) {
27+
throw newErr
28+
}
2629
}
27-
}
30+
})
2831
}

services/libs/integrations/src/integrations/discord/api/getChannels.ts

Lines changed: 34 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { DiscordApiChannel, DiscordGetChannelsInput, DiscordGetMessagesInput } f
44
import getMessages from './getMessages'
55
import { IProcessStreamContext } from '../../../types'
66
import { handleDiscordError } from './errorHandler'
7+
import { retryWrapper } from './handleRateLimit'
78

89
/**
910
* Try if a channel is readable
@@ -40,43 +41,45 @@ async function getChannels(
4041
},
4142
}
4243

43-
try {
44-
const response = await axios(config)
45-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
46-
const result: any = response.data
47-
48-
if (tryChannels) {
44+
return await retryWrapper(3, async () => {
45+
try {
46+
const response = await axios(config)
4947
// eslint-disable-next-line @typescript-eslint/no-explicit-any
50-
const out: any[] = []
51-
for (const channel of result) {
52-
const limit = await tryChannel(
53-
{
54-
channelId: channel.id,
55-
token: input.token,
56-
perPage: 1,
57-
page: undefined,
58-
},
59-
ctx,
60-
)
61-
if (limit) {
62-
out.push(channel)
63-
if (limit <= 1 && limit !== false) {
64-
await timeout(5 * 1000)
48+
const result: any = response.data
49+
50+
if (tryChannels) {
51+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
52+
const out: any[] = []
53+
for (const channel of result) {
54+
const limit = await tryChannel(
55+
{
56+
channelId: channel.id,
57+
token: input.token,
58+
perPage: 1,
59+
page: undefined,
60+
},
61+
ctx,
62+
)
63+
if (limit) {
64+
out.push(channel)
65+
if (limit <= 1 && limit !== false) {
66+
await timeout(5 * 1000)
67+
}
6568
}
6669
}
70+
return out
6771
}
68-
return out
69-
}
7072

71-
return result
72-
} catch (err) {
73-
const newErr = handleDiscordError(err, config, { input }, ctx)
74-
if (newErr) {
75-
throw newErr
76-
} else {
77-
return []
73+
return result
74+
} catch (err) {
75+
const newErr = handleDiscordError(err, config, { input }, ctx)
76+
if (newErr) {
77+
throw newErr
78+
} else {
79+
return []
80+
}
7881
}
79-
}
82+
})
8083
}
8184

8285
export default getChannels

services/libs/integrations/src/integrations/discord/api/getMember.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import axios, { AxiosRequestConfig } from 'axios'
22
import { DiscordApiMember } from '../types'
33
import { handleDiscordError } from './errorHandler'
44
import { IProcessStreamContext } from '../../../types'
5+
import { retryWrapper } from './handleRateLimit'
56

67
export const getMember = async (
78
guildId: string,
@@ -18,13 +19,15 @@ export const getMember = async (
1819
},
1920
}
2021

21-
try {
22-
const response = await axios(config)
23-
return response.data
24-
} catch (err) {
25-
const newErr = handleDiscordError(err, config, { guildId, userId }, ctx)
26-
if (newErr) {
27-
throw newErr
22+
return await retryWrapper(3, async () => {
23+
try {
24+
const response = await axios(config)
25+
return response.data
26+
} catch (err) {
27+
const newErr = handleDiscordError(err, config, { guildId, userId }, ctx)
28+
if (newErr) {
29+
throw newErr
30+
}
2831
}
29-
}
32+
})
3033
}

services/libs/integrations/src/integrations/discord/api/getMembers.ts

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import axios from 'axios'
22
import { DiscordApiMember, DiscordGetMembersInput, DiscordGetMembersOutput } from '../types'
33
import { IProcessStreamContext } from '../../../types'
44
import { handleDiscordError } from './errorHandler'
5+
import { retryWrapper } from './handleRateLimit'
56

67
async function getMembers(
78
input: DiscordGetMembersInput,
@@ -19,24 +20,27 @@ async function getMembers(
1920
Authorization: input.token,
2021
},
2122
}
22-
try {
23-
const response = await axios(config)
24-
const records: DiscordApiMember[] = response.data
25-
const limit = parseInt(response.headers['x-ratelimit-remaining'], 10)
26-
const timeUntilReset = parseInt(response.headers['x-ratelimit-reset-after'], 10)
27-
const nextPage = records.length > 0 ? (records[records.length - 1].user.id as string) : ''
28-
return {
29-
records,
30-
nextPage,
31-
limit,
32-
timeUntilReset,
33-
}
34-
} catch (err) {
35-
const newErr = handleDiscordError(err, config, { input }, ctx)
36-
if (newErr) {
37-
throw newErr
23+
24+
return await retryWrapper(3, async () => {
25+
try {
26+
const response = await axios(config)
27+
const records: DiscordApiMember[] = response.data
28+
const limit = parseInt(response.headers['x-ratelimit-remaining'], 10)
29+
const timeUntilReset = parseInt(response.headers['x-ratelimit-reset-after'], 10)
30+
const nextPage = records.length > 0 ? (records[records.length - 1].user.id as string) : ''
31+
return {
32+
records,
33+
nextPage,
34+
limit,
35+
timeUntilReset,
36+
}
37+
} catch (err) {
38+
const newErr = handleDiscordError(err, config, { input }, ctx)
39+
if (newErr) {
40+
throw newErr
41+
}
3842
}
39-
}
43+
})
4044
}
4145

4246
export default getMembers
Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import axios, { AxiosRequestConfig } from 'axios'
22
import { handleDiscordError } from './errorHandler'
33
import { IProcessStreamContext } from '../../../types'
4+
import { retryWrapper } from './handleRateLimit'
45

56
export const getMessage = async (
67
channelId: string,
@@ -16,45 +17,47 @@ export const getMessage = async (
1617
},
1718
}
1819

19-
try {
20-
const response = await axios(config)
21-
return response.data
22-
} catch (err) {
23-
if (
24-
err.response &&
25-
err.response.status === 404 &&
26-
err.response.data &&
27-
err.response.data.message === 'Unknown Channel' &&
28-
err.response.data.code === 10003
29-
) {
30-
ctx.log.warn(
31-
{ channelId, messageId },
32-
'Discord API returned Unknown Channel error when fetching message during webhook processing, skipping message.',
33-
)
34-
return null
35-
} else if (
36-
err.response &&
37-
err.response.status === 404 &&
38-
err.response.data &&
39-
err.response.data.message === 'Unknown Message' &&
40-
err.response.data.code === 10008
41-
) {
42-
ctx.log.warn(
43-
{ channelId, messageId },
44-
'Discord API returned Unknown Message error when fetching message during webhook processing, skipping message.',
45-
)
46-
return null
47-
} else if (err.response && err.response.status === 404) {
48-
ctx.log.warn(
49-
{ channelId, messageId },
50-
'Discord API returned 404 error when fetching message during webhook processing, skipping message.',
51-
)
52-
return null
53-
} else {
54-
const newErr = handleDiscordError(err, config, { channelId, messageId }, ctx)
55-
if (newErr) {
56-
throw newErr
20+
return await retryWrapper(3, async () => {
21+
try {
22+
const response = await axios(config)
23+
return response.data
24+
} catch (err) {
25+
if (
26+
err.response &&
27+
err.response.status === 404 &&
28+
err.response.data &&
29+
err.response.data.message === 'Unknown Channel' &&
30+
err.response.data.code === 10003
31+
) {
32+
ctx.log.warn(
33+
{ channelId, messageId },
34+
'Discord API returned Unknown Channel error when fetching message during webhook processing, skipping message.',
35+
)
36+
return null
37+
} else if (
38+
err.response &&
39+
err.response.status === 404 &&
40+
err.response.data &&
41+
err.response.data.message === 'Unknown Message' &&
42+
err.response.data.code === 10008
43+
) {
44+
ctx.log.warn(
45+
{ channelId, messageId },
46+
'Discord API returned Unknown Message error when fetching message during webhook processing, skipping message.',
47+
)
48+
return null
49+
} else if (err.response && err.response.status === 404) {
50+
ctx.log.warn(
51+
{ channelId, messageId },
52+
'Discord API returned 404 error when fetching message during webhook processing, skipping message.',
53+
)
54+
return null
55+
} else {
56+
const newErr = handleDiscordError(err, config, { channelId, messageId }, ctx)
57+
if (newErr) {
58+
throw newErr
59+
}
5760
}
5861
}
59-
}
62+
})
6063
}

services/libs/integrations/src/integrations/discord/api/getMessages.ts

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import axios from 'axios'
22
import { DiscordApiMessage, DiscordParsedReponse, DiscordGetMessagesInput } from '../types'
33
import { IProcessStreamContext } from '../../../types'
44
import { handleDiscordError } from './errorHandler'
5+
import { retryWrapper } from './handleRateLimit'
56

67
async function getMessages(
78
input: DiscordGetMessagesInput,
@@ -21,33 +22,35 @@ async function getMessages(
2122
},
2223
}
2324

24-
try {
25-
const response = await axios(config)
26-
const records: DiscordApiMessage[] = response.data
25+
return await retryWrapper(3, async () => {
26+
try {
27+
const response = await axios(config)
28+
const records: DiscordApiMessage[] = response.data
2729

28-
const limit = parseInt(response.headers['x-ratelimit-remaining'], 10)
29-
const timeUntilReset = parseInt(response.headers['x-ratelimit-reset-after'], 10)
30-
const nextPage = records.length > 0 ? records[records.length - 1].id : ''
31-
return {
32-
records,
33-
nextPage,
34-
limit,
35-
timeUntilReset,
36-
}
37-
} catch (err) {
38-
if (!showErrors) {
30+
const limit = parseInt(response.headers['x-ratelimit-remaining'], 10)
31+
const timeUntilReset = parseInt(response.headers['x-ratelimit-reset-after'], 10)
32+
const nextPage = records.length > 0 ? records[records.length - 1].id : ''
3933
return {
40-
records: [],
41-
nextPage: '',
42-
limit: 0,
43-
timeUntilReset: 0,
34+
records,
35+
nextPage,
36+
limit,
37+
timeUntilReset,
38+
}
39+
} catch (err) {
40+
if (!showErrors) {
41+
return {
42+
records: [],
43+
nextPage: '',
44+
limit: 0,
45+
timeUntilReset: 0,
46+
}
47+
}
48+
const newErr = handleDiscordError(err, config, { input }, ctx)
49+
if (newErr) {
50+
throw newErr
4451
}
4552
}
46-
const newErr = handleDiscordError(err, config, { input }, ctx)
47-
if (newErr) {
48-
throw newErr
49-
}
50-
}
53+
})
5154
}
5255

5356
export default getMessages

services/libs/integrations/src/integrations/discord/api/getThreads.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import axios from 'axios'
22
import { DiscordApiChannel, DiscordGetChannelsInput } from '../types'
33
import { IProcessStreamContext } from '../../../types'
44
import { handleDiscordError } from './errorHandler'
5+
import { retryWrapper } from './handleRateLimit'
56

67
async function getThreads(
78
input: DiscordGetChannelsInput,
@@ -14,15 +15,18 @@ async function getThreads(
1415
Authorization: input.token,
1516
},
1617
}
17-
try {
18-
const response = await axios(config)
19-
return response.data.threads
20-
} catch (err) {
21-
const newErr = handleDiscordError(err, config, { input }, ctx)
22-
if (newErr) {
23-
throw newErr
18+
19+
return await retryWrapper(3, async () => {
20+
try {
21+
const response = await axios(config)
22+
return response.data.threads
23+
} catch (err) {
24+
const newErr = handleDiscordError(err, config, { input }, ctx)
25+
if (newErr) {
26+
throw newErr
27+
}
2428
}
25-
}
29+
})
2630
}
2731

2832
export default getThreads

0 commit comments

Comments
 (0)