diff --git a/packages/common/nbstore/src/impls/cloud/http.ts b/packages/common/nbstore/src/impls/cloud/http.ts index f327d1ede..675653a52 100644 --- a/packages/common/nbstore/src/impls/cloud/http.ts +++ b/packages/common/nbstore/src/impls/cloud/http.ts @@ -3,26 +3,24 @@ import { gqlFetcherFactory } from '@affine/graphql'; import { DummyConnection } from '../../connection'; +const TIMEOUT = 15000; + export class HttpConnection extends DummyConnection { readonly fetch = async (input: string, init?: RequestInit) => { const externalSignal = init?.signal; if (externalSignal?.aborted) { throw externalSignal.reason; } - const abortController = new AbortController(); - externalSignal?.addEventListener('abort', reason => { - abortController.abort(reason); - }); - const timeout = 15000; - const timeoutId = setTimeout(() => { - abortController.abort(new Error('request timeout')); - }, timeout); + const signals = [AbortSignal.timeout(TIMEOUT)]; + if (externalSignal) signals.push(externalSignal); + + const combinedSignal = AbortSignal.any(signals); const res = await globalThis .fetch(new URL(input, this.serverBaseUrl), { ...init, - signal: abortController.signal, + signal: combinedSignal, headers: { ...this.requestHeaders, ...init?.headers, @@ -30,16 +28,18 @@ export class HttpConnection extends DummyConnection { }, }) .catch(err => { + const message = + err.name === 'TimeoutError' ? 'request timeout' : err.message; + throw new UserFriendlyError({ status: 504, code: 'NETWORK_ERROR', type: 'NETWORK_ERROR', name: 'NETWORK_ERROR', - message: `Network error: ${err.message}`, + message: `Network error: ${message}`, stacktrace: err.stack, }); }); - clearTimeout(timeoutId); if (!res.ok && res.status !== 404) { if (res.status === 413) { throw new UserFriendlyError({