mirror of
https://github.com/outline/outline.git
synced 2026-06-13 03:14:59 +03:00
fix: Retry Notion API 5xx errors with exponential backoff (#12481)
The Notion API can return transient 5xx errors during imports. Retry these up to 8 times with exponential backoff, tracked separately from the existing timeout/rate-limit retry budget.
This commit is contained in:
@@ -6,6 +6,7 @@ import {
|
||||
isFullPageOrDatabase,
|
||||
isFullUser,
|
||||
RequestTimeoutError,
|
||||
UnknownHTTPResponseError,
|
||||
} from "@notionhq/client";
|
||||
import type {
|
||||
BlockObjectResponse,
|
||||
@@ -60,6 +61,7 @@ export class NotionClient {
|
||||
private limiter: ReturnType<typeof RateLimit>;
|
||||
private pageSize = 100;
|
||||
private maxRetries = 3;
|
||||
private maxServerErrorRetries = 8;
|
||||
private retryDelay = 1000;
|
||||
private skipChildrenForBlock = [
|
||||
"unsupported",
|
||||
@@ -94,6 +96,7 @@ export class NotionClient {
|
||||
*/
|
||||
private async fetchWithRetry<T>(apiCall: () => Promise<T>): Promise<T> {
|
||||
let retries = 0;
|
||||
let serverErrorRetries = 0;
|
||||
|
||||
// oxlint-disable-next-line no-constant-condition
|
||||
while (true) {
|
||||
@@ -149,6 +152,32 @@ export class NotionClient {
|
||||
);
|
||||
}
|
||||
|
||||
// Check if this is a server-side error (5xx) — Notion's API can be
|
||||
// unreliable, so retry these for longer with exponential backoff.
|
||||
if (
|
||||
(error instanceof APIResponseError ||
|
||||
error instanceof UnknownHTTPResponseError) &&
|
||||
error.status >= 500
|
||||
) {
|
||||
if (serverErrorRetries < this.maxServerErrorRetries) {
|
||||
serverErrorRetries++;
|
||||
const delay = this.retryDelay * 2 ** (serverErrorRetries - 1);
|
||||
Logger.info(
|
||||
"task",
|
||||
`Notion API returned ${error.status}, retrying in ${delay}ms (retry ${serverErrorRetries}/${this.maxServerErrorRetries})`
|
||||
);
|
||||
|
||||
// Wait before retrying
|
||||
await new Promise((resolve) => setTimeout(resolve, delay));
|
||||
continue;
|
||||
}
|
||||
|
||||
Logger.warn(
|
||||
`Notion API returned ${error.status} after ${this.maxServerErrorRetries} retries`,
|
||||
{ error: error.message }
|
||||
);
|
||||
}
|
||||
|
||||
// Re-throw the error if it's not a rate limit issue or we've exhausted retries
|
||||
throw error;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user