Skip to content

Commit d89e819

Browse files
committed
Fix flush() to retry fetch() on transient errors
This changes flush() to retry the fetch() call on transient errors such as EPIPE, ECONNREFUSED, and ECONNRESET.
1 parent 5db0765 commit d89e819

1 file changed

Lines changed: 24 additions & 2 deletions

File tree

src/http/stream.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -329,8 +329,7 @@ export class HttpStream extends Stream implements SqlOwner {
329329
let promise;
330330
try {
331331
const request = createRequest();
332-
const fetch = this.#fetch;
333-
promise = fetch(request);
332+
promise = this.#fetchWithRetry(request);
334333
} catch (error) {
335334
promise = Promise.reject(error);
336335
}
@@ -356,6 +355,20 @@ export class HttpStream extends Stream implements SqlOwner {
356355
});
357356
}
358357

358+
#fetchWithRetry(request: Request, retryCount: number = 3, backoff: number = 100): Promise<Response> {
359+
const fetch = this.#fetch;
360+
return fetch(request).catch((error) => {
361+
if (isRetryableError(error)) {
362+
if (retryCount > 0) {
363+
return new Promise((resolve) => setTimeout(resolve, backoff)).then(() => {
364+
return this.#fetchWithRetry(request, retryCount - 1, backoff * 2);
365+
});
366+
}
367+
}
368+
throw error;
369+
});
370+
}
371+
359372
#createPipelineRequest(pipeline: Array<PipelineEntry>, endpoint: Endpoint): Request {
360373
return this.#createRequest<proto.PipelineReqBody>(
361374
new URL(endpoint.pipelinePath, this.#baseUrl),
@@ -417,6 +430,15 @@ export class HttpStream extends Stream implements SqlOwner {
417430
}
418431
}
419432

433+
function isRetryableError(error: any): boolean {
434+
if (!error.errno) {
435+
return false;
436+
}
437+
return error.errno === "EPIPE"
438+
|| error.errno === "ECONNREFUSED"
439+
|| error.errno === "ECONNRESET";
440+
}
441+
420442
function handlePipelineResponse(pipeline: Array<PipelineEntry>, respBody: proto.PipelineRespBody): void {
421443
if (respBody.results.length !== pipeline.length) {
422444
throw new ProtoError("Server returned unexpected number of pipeline results");

0 commit comments

Comments
 (0)