File tree Expand file tree Collapse file tree 6 files changed +44
-11
lines changed Expand file tree Collapse file tree 6 files changed +44
-11
lines changed Original file line number Diff line number Diff line change @@ -169,5 +169,7 @@ describe("versions upload", () => {
169169 Uploaded test-name (TIMINGS)
170170 Worker Version ID: 51e4886e-2db7-4900-8d38-fbfecfeab993"
171171 ` ) ;
172+
173+ expect ( std . info ) . toContain ( "Retrying API call after error..." ) ;
172174 } ) ;
173175} ) ;
Original file line number Diff line number Diff line change @@ -49,7 +49,7 @@ import {
4949} from "../sourcemap" ;
5050import triggersDeploy from "../triggers/deploy" ;
5151import { printBindings } from "../utils/print-bindings" ;
52- import { retryOnError } from "../utils/retry" ;
52+ import { retryOnAPIFailure } from "../utils/retry" ;
5353import {
5454 createDeployment ,
5555 patchNonVersionedScriptSettings ,
@@ -826,7 +826,7 @@ See https://developers.cloudflare.com/workers/platform/compatibility-dates for m
826826 // If we're using the new APIs, first upload the version
827827 if ( canUseNewVersionsDeploymentsApi ) {
828828 // Upload new version
829- const versionResult = await retryOnError ( async ( ) =>
829+ const versionResult = await retryOnAPIFailure ( async ( ) =>
830830 fetchResult < ApiVersion > (
831831 `/accounts/${ accountId } /workers/scripts/${ scriptName } /versions` ,
832832 {
@@ -861,7 +861,7 @@ See https://developers.cloudflare.com/workers/platform/compatibility-dates for m
861861 startup_time_ms : versionResult . startup_time_ms ,
862862 } ;
863863 } else {
864- result = await retryOnError ( async ( ) =>
864+ result = await retryOnAPIFailure ( async ( ) =>
865865 fetchResult < {
866866 id : string | null ;
867867 etag : string | null ;
Original file line number Diff line number Diff line change @@ -88,6 +88,10 @@ export class APIError extends ParseError {
8888 return false ;
8989 }
9090
91+ isRetryable ( ) {
92+ return String ( this . #status) . startsWith ( "5" ) ;
93+ }
94+
9195 // Allow `APIError`s to be marked as handled.
9296 #reportable = true ;
9397 get reportable ( ) {
Original file line number Diff line number Diff line change @@ -5,7 +5,7 @@ import { logger } from "../logger";
55import * as metrics from "../metrics" ;
66import { APIError } from "../parse" ;
77import { requireAuth } from "../user" ;
8- import { retryOnError } from "../utils/retry" ;
8+ import { retryOnAPIFailure } from "../utils/retry" ;
99import { printWranglerBanner } from "../wrangler-banner" ;
1010import {
1111 createPipeline ,
@@ -63,7 +63,7 @@ async function authorizeR2Bucket(
6363
6464 // Wait for token to settle/propagate, retry up to 10 times, with 1s waits in-between errors
6565 ! __testSkipDelaysFlag &&
66- ( await retryOnError (
66+ ( await retryOnAPIFailure (
6767 async ( ) => {
6868 await r2 . send (
6969 new HeadBucketCommand ( {
Original file line number Diff line number Diff line change 11import { setTimeout } from "node:timers/promises" ;
2+ import chalk from "chalk" ;
3+ import { logger } from "../logger" ;
4+ import { APIError } from "../parse" ;
25
3- export async function retryOnError < T > (
6+ const MAX_ATTEMPTS = 3 ;
7+ /**
8+ * Wrap around calls to the Cloudflare API to automatically retry
9+ * calls that result in a 5xx error code, indicating an API failure.
10+ *
11+ * Retries will back off at a rate of 1000ms per retry, with a 0ms delay for the first retry
12+ *
13+ * Note: this will not retry 4xx or other failures, as those are
14+ * likely legitimate user error.
15+ */
16+ export async function retryOnAPIFailure < T > (
417 action : ( ) => T | Promise < T > ,
5- backoff = 2_000 ,
6- attempts = 3
18+ backoff = 0 ,
19+ attempts = MAX_ATTEMPTS
720) : Promise < T > {
821 try {
922 return await action ( ) ;
1023 } catch ( err ) {
24+ if (
25+ ( err instanceof APIError && ! err . isRetryable ( ) ) ||
26+ ! ( err instanceof TypeError )
27+ ) {
28+ throw err ;
29+ }
30+
31+ logger . info ( chalk . dim ( `Retrying API call after error...` ) ) ;
32+ logger . debug ( err ) ;
33+
1134 if ( attempts <= 1 ) {
1235 throw err ;
1336 }
1437
1538 await setTimeout ( backoff ) ;
16- return retryOnError ( action , backoff , attempts - 1 ) ;
39+ return retryOnAPIFailure (
40+ action ,
41+ backoff + ( MAX_ATTEMPTS - attempts ) * 1000 ,
42+ attempts - 1
43+ ) ;
1744 }
1845}
Original file line number Diff line number Diff line change @@ -53,7 +53,7 @@ import { getRules } from "../utils/getRules";
5353import { getScriptName } from "../utils/getScriptName" ;
5454import { isLegacyEnv } from "../utils/isLegacyEnv" ;
5555import { printBindings } from "../utils/print-bindings" ;
56- import { retryOnError } from "../utils/retry" ;
56+ import { retryOnAPIFailure } from "../utils/retry" ;
5757import type { AssetsOptions } from "../assets" ;
5858import type { Config } from "../config" ;
5959import type { Rule } from "../config/environment" ;
@@ -741,7 +741,7 @@ See https://developers.cloudflare.com/workers/platform/compatibility-dates for m
741741 try {
742742 const body = createWorkerUploadForm ( worker ) ;
743743
744- const result = await retryOnError ( async ( ) =>
744+ const result = await retryOnAPIFailure ( async ( ) =>
745745 fetchResult < {
746746 id : string ;
747747 startup_time_ms : number ;
You can’t perform that action at this time.
0 commit comments