toeverything/AFFiNE · error · UserFriendlyError
NETWORK_ERROR
NETWORK_ERROR
Error message
Network error: ${err.message} What it means
HttpConnection.fetch wraps globalThis.fetch; any fetch rejection (DNS failure, connection refused, CORS, TLS error, or the built-in 15s default timeout aborting with 'request timeout') is converted into a UserFriendlyError with status 504 and code/type/name NETWORK_ERROR. The original message (e.g. 'Failed to fetch' or 'request timeout') and stack are preserved inside.
Source
Thrown at packages/common/nbstore/src/impls/cloud/http.ts:40
const timeoutId =
timeout > 0
? setTimeout(() => {
abortController.abort(new Error('request timeout'));
}, timeout)
: undefined;
const res = await globalThis
.fetch(new URL(input, this.serverBaseUrl), {
...init,
signal: abortController.signal,
headers: {
...this.requestHeaders,
...init?.headers,
'x-affine-version': BUILD_CONFIG.appVersion,
},
})
.catch(err => {
throw new UserFriendlyError({
status: 504,
code: 'NETWORK_ERROR',
type: 'NETWORK_ERROR',
name: 'NETWORK_ERROR',
message: `Network error: ${err.message}`,
stacktrace: err.stack,
});
});
if (timeoutId) {
clearTimeout(timeoutId);
}
if (!res.ok && res.status !== 404) {
if (res.status === 413) {
throw new UserFriendlyError({
status: 413,
code: 'CONTENT_TOO_LARGE',
type: 'CONTENT_TOO_LARGE',
name: 'CONTENT_TOO_LARGE',View on GitHub (pinned to b4c8548c09)
Solutions
- If it's a timeout ('Network error: request timeout'), pass a larger timeout in init (connection.fetch(url, { timeout: 60000 })) or 0 to disable — note blob uploads already set no timeout.
- Verify serverBaseUrl is correct and the server is reachable (curl the URL from the same environment).
- For offline/CORS: check network connectivity and the server's CORS configuration for the client origin.
- Handle it in UI: err instanceof UserFriendlyError && err.code === 'NETWORK_ERROR' → offer retry; keep the original message for diagnostics.
Example fix
// before
const res = await connection.fetch('/api/workspaces/' + id + '/blobs/' + key);
// >15s downloads/reads throw Network error: request timeout
// after
const res = await connection.fetch(
'/api/workspaces/' + id + '/blobs/' + key,
{ timeout: 60_000 }
); Defensive patterns
Strategy: retry
Validate before calling
async function reachable(baseUrl: string): Promise<boolean> {
try { await fetch(new URL('/api/workspaces', baseUrl), { method: 'HEAD' }); return true; } catch { return false; }
} Type guard
import { UserFriendlyError } from '@affine/error';
const isNetworkError = (e: unknown): e is UserFriendlyError =>
e instanceof UserFriendlyError && e.code === 'NETWORK_ERROR'; Try / catch
async function fetchWithRetry(url: string, init?: RequestInit & { timeout?: number }, tries = 3) {
for (let i = 0; ; i++) {
try { return await connection.fetch(url, init); }
catch (e) {
if (i < tries - 1 && e instanceof UserFriendlyError && e.code === 'NETWORK_ERROR') {
await new Promise(r => setTimeout(r, 2 ** i * 500)); continue;
}
throw e;
}
}
} Prevention
- Pass an explicit timeout sized to the operation (uploads/downloads: large or 0)
- Check connectivity before long sync sessions and queue work offline
- Configure server CORS for the exact client origin
- Never retry non-idempotent mutations blindly — only GETs/fetches
When it happens
Trigger: Calling connection.fetch/gql while offline; wrong/unreachable serverBaseUrl; expired/self-signed certificates; a request exceeding init.timeout (default 15000ms — the abort surfaces as 'Network error: request timeout'); CORS blocking in the browser.
Common situations: Client lost connectivity mid-session; dev pointing at a localhost server that is not running; slow blob uploads hitting the 15s default because the timeout option wasn't raised; VPN/DNS issues; deploying the web app on a domain not allowed by server CORS.
Related errors
- network_error
- user_not_found
- action_forbidden
- Invalid config for module [${module}] with key [${key}] Valu
- bad_request
AI-assisted analysis of toeverything/AFFiNE@b4c8548c09 (2026-08-18).
Data as JSON: /api/errors/b49ad8394e07d76a.
Report an issue: GitHub.