@@ -256,11 +256,49 @@ const notionLimiter = new RateLimiter({
256256let notionClient : Client ;
257257
258258async function getPageMetadata ( id : string ) : Promise < GetPageResponse > {
259+ return await executeWithRateLimitAndRetries ( `pages.retrieve(${ id } )` , ( ) => {
260+ return notionClient . pages . retrieve ( {
261+ page_id : id ,
262+ } ) ;
263+ } ) ;
264+ }
265+
266+ // While everything works fine locally, on Github Actions we are getting a lot of timeouts, so
267+ // we're trying this extra retry-able wrapper.
268+ export async function executeWithRateLimitAndRetries < T > (
269+ label : string ,
270+ asyncFunction : ( ) => Promise < T >
271+ ) : Promise < T > {
259272 await rateLimit ( ) ;
273+ const kRetries = 10 ;
274+ let lastException = undefined ;
275+ for ( let i = 0 ; i < kRetries ; i ++ ) {
276+ try {
277+ return await asyncFunction ( ) ;
278+ } catch ( e : any ) {
279+ lastException = e ;
280+ if (
281+ e ?. code === "notionhq_client_request_timeout" ||
282+ e . message . includes ( "timeout" ) ||
283+ e . message . includes ( "Timeout" ) ||
284+ e . message . includes ( "limit" ) ||
285+ e . message . includes ( "Limit" )
286+ ) {
287+ const secondsToWait = i + 1 ;
288+ info (
289+ `While doing "${ label } ", got error "${
290+ e . message as string
291+ } ". Will retry after ${ secondsToWait } s...`
292+ ) ;
293+ await new Promise ( resolve => setTimeout ( resolve , 1000 * secondsToWait ) ) ;
294+ } else {
295+ throw e ;
296+ }
297+ }
298+ }
260299
261- return await notionClient . pages . retrieve ( {
262- page_id : id ,
263- } ) ;
300+ error ( `Error: could not complete "${ label } " after ${ kRetries } retries.` ) ;
301+ throw lastException ;
264302}
265303
266304async function rateLimit ( ) {
@@ -275,18 +313,19 @@ async function getBlockChildren(id: string): Promise<NotionBlock[]> {
275313 // the first response we get, then keep adding to its array of blocks
276314 // with each subsequent response
277315 let overallResult : ListBlockChildrenResponse | undefined = undefined ;
278- let start_cursor = undefined ;
316+ let start_cursor : string | undefined | null = undefined ;
279317
280318 // Note: there is a now a collectPaginatedAPI() in the notion client, so
281319 // we could switch to using that (I don't know if it does rate limiting?)
282320 do {
283- await rateLimit ( ) ;
284-
285321 const response : ListBlockChildrenResponse =
286- await notionClient . blocks . children . list ( {
287- start_cursor : start_cursor ,
288- block_id : id ,
322+ await executeWithRateLimitAndRetries ( `getBlockChildren(${ id } )` , ( ) => {
323+ return notionClient . blocks . children . list ( {
324+ start_cursor : start_cursor as string | undefined ,
325+ block_id : id ,
326+ } ) ;
289327 } ) ;
328+
290329 if ( ! overallResult ) {
291330 overallResult = response ;
292331 } else {
0 commit comments