diff --git a/src/api/api.ts b/src/api/api.ts index a43a79293..7c4df3a23 100644 --- a/src/api/api.ts +++ b/src/api/api.ts @@ -21,6 +21,7 @@ import { getBestListingsAPIPath, getCancelOrderPath, } from "./apiPaths"; +import { OpenSeaRatelimitError } from "./errors"; import { BuildOfferResponse, GetCollectionResponse, @@ -755,6 +756,19 @@ export class OpenSeaAPI { const response = await req.send(); if (!response.ok()) { + if (response.statusCode === 599 || response.statusCode === 429) { + let retryAfter: number | undefined; + const retryAfterHeader = + response.headers["retry-after"] || response.headers["Retry-After"]; + if (retryAfterHeader) { + retryAfter = parseInt(retryAfterHeader, 10); + } + throw new OpenSeaRatelimitError( + `${response.statusCode} ${response.statusMessage}`, + retryAfter, + response.bodyJson, + ); + } // If an errors array is returned, throw with the error messages. const errors = response.bodyJson?.errors; if (errors?.length > 0) { diff --git a/src/api/errors.ts b/src/api/errors.ts new file mode 100644 index 000000000..2f43199f8 --- /dev/null +++ b/src/api/errors.ts @@ -0,0 +1,12 @@ +export class OpenSeaRatelimitError extends Error { + public retryAfter?: number; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + public responseBody?: any; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + constructor(message: string, retryAfter?: number, responseBody?: any) { + super(message); + this.name = "OpenSeaRatelimitError"; + this.retryAfter = retryAfter; + this.responseBody = responseBody; + } +}