Skip to content

Commit 1cc0a2b

Browse files
committed
Retry non-fatal ETIMEDOUT error in database:import
1 parent 5a8b2ac commit 1cc0a2b

File tree

1 file changed

+21
-4
lines changed

1 file changed

+21
-4
lines changed

src/database/import.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import * as StreamObject from "stream-json/streamers/StreamObject";
66

77
import { URL } from "url";
88
import { Client, ClientResponse } from "../apiv2";
9+
import { FetchError } from "node-fetch";
910
import { FirebaseError } from "../error";
1011
import * as pLimit from "p-limit";
1112

@@ -121,14 +122,30 @@ export default class DatabaseImporter {
121122
}
122123

123124
private writeChunk(chunk: Data): Promise<ClientResponse<JsonType>> {
124-
return this.limit(() =>
125-
this.client.request({
125+
const doRequest = (): Promise<ClientResponse<JsonType>> => {
126+
return this.client.request({
126127
method: "PUT",
127128
path: chunk.pathname + ".json",
128129
body: JSON.stringify(chunk.json),
129130
queryParams: this.dbUrl.searchParams,
130-
})
131-
);
131+
});
132+
};
133+
return this.limit(async () => {
134+
try {
135+
return await doRequest();
136+
} catch (err: any) {
137+
const isTimeoutErr =
138+
err instanceof FirebaseError &&
139+
err.original instanceof FetchError &&
140+
err.original.code === "ETIMEDOUT";
141+
if (isTimeoutErr) {
142+
// RTDB connection timeouts are transient and can be retried
143+
await new Promise((res) => setTimeout(res, 1000));
144+
return await doRequest();
145+
}
146+
throw err;
147+
}
148+
});
132149
}
133150

134151
private chunkData({ json, pathname }: Data): ChunkedData {

0 commit comments

Comments
 (0)