@@ -100,28 +100,47 @@ async function getSlackChannelsForToken(integration: AuthenticatableIntegration)
100
100
101
101
type Channels = Awaited < ReturnType < WebClient [ "conversations" ] [ "list" ] > > [ "channels" ] ;
102
102
103
- async function getSlackConversationsPage ( client : WebClient , nextCursor ?: string ) {
104
- return client . conversations . list ( {
105
- types : "public_channel,private_channel" ,
106
- exclude_archived : true ,
107
- cursor : nextCursor ,
108
- } ) ;
109
- }
110
-
111
103
async function getAllSlackConversations ( client : WebClient ) {
112
104
let nextCursor : string | undefined = undefined ;
113
105
let channels : Channels = [ ] ;
114
106
115
- do {
116
- const response = await getSlackConversationsPage ( client , nextCursor ) ;
117
-
118
- if ( ! response . ok ) {
119
- throw new Error ( `Failed to get channels: ${ response . error } ` ) ;
107
+ try {
108
+ do {
109
+ // The `tryCatch` util runs into a type error due to self referencing.
110
+ // So we fall back to a good old try/catch block here.
111
+ const response = await client . conversations . list ( {
112
+ types : "public_channel,private_channel" ,
113
+ exclude_archived : true ,
114
+ cursor : nextCursor ,
115
+ limit : 999 ,
116
+ } ) ;
117
+
118
+ channels = channels . concat ( response . channels ?? [ ] ) ;
119
+ nextCursor = response . response_metadata ?. next_cursor ;
120
+ } while ( nextCursor ) ;
121
+ } catch ( error ) {
122
+ if ( error && isSlackError ( error ) && error . data . error === "ratelimited" ) {
123
+ logger . warn ( "Rate limiting issue occurred while fetching Slack channels" , {
124
+ error,
125
+ } ) ;
126
+
127
+ // This is a workaround to the current way we handle Slack channels for creating alerts.
128
+ // For workspaces with a lot of channels (>10000) we might hit the rate limit for this slack endpoint,
129
+ // as multiple requests are needed to fetch all channels.
130
+ // We use the largest allowed page size of 999 to reduce the chance of hitting the rate limit.
131
+
132
+ // This is mainly due to workspaces with a large number of archived channels,
133
+ // which this slack endpoint unfortunately filters out only after fetching the page of channels without applying any filters first.
134
+ // https://api.slack.com/methods/conversations.list#markdown
135
+
136
+ // We expect most workspaces not to run into this issue, but if they do, we at least return some channels.
137
+ // In the future, we might revisit the way we handle Slack channels and cache them on our side to support
138
+ // proper searching. Until then, we track occurrences of this issue using a metric.
139
+ return channels ;
120
140
}
121
141
122
- channels = channels . concat ( response . channels ?? [ ] ) ;
123
- nextCursor = response . response_metadata ?. next_cursor ;
124
- } while ( nextCursor ) ;
142
+ throw error ;
143
+ }
125
144
126
145
return channels ;
127
146
}
0 commit comments