hcengineering/platform · error · NetworkError
Network error: ${String(err)}
Error message
Network error: ${String(err)} What it means
fetchSafe wraps the underlying fetch call and converts low-level network failures into a typed NetworkError with the message `Network error: ${String(err)}`. This happens when fetch itself rejects — DNS failure, connection refused, TLS errors, aborted requests — before any HTTP response exists. The original error text is embedded in the message for diagnosis.
Source
Thrown at packages/payment-client/src/client.ts:161
const response = await fetchSafe(url, { headers: { ...this.headers } })
return (await response.json()) as CheckoutStatus
}
}
/**
* Safe fetch wrapper that handles errors consistently
* @param url - URL to fetch
* @param init - Fetch options
* @returns Response
* @throws NetworkError on network issues
* @throws PaymentError on non-ok responses
*/
async function fetchSafe (url: string | URL, init?: RequestInit): Promise<Response> {
let response
try {
response = await fetch(url, init)
} catch (err: any) {
throw new NetworkError(`Network error: ${String(err)}`)
}
if (!response.ok) {
const text = await response.text()
try {
const error = JSON.parse(text)
throw new PaymentError(error.error ?? text)
} catch {
throw new PaymentError(`Payment service error: ${response.status} ${text}`)
}
}
return response
}
View on GitHub (pinned to 63e28dc964)
Solutions
- Read the embedded cause in the message (e.g. 'fetch failed', 'ENOTFOUND', 'ECONNREFUSED') to identify the network problem.
- Verify the payment service URL is correct and the service is running/reachable (curl the health endpoint).
- Check network connectivity, DNS, and egress/firewall rules from the client environment.
- Implement retry with backoff for transient outages; NetworkError is the type to match for retry decisions.
Example fix
// before
const res = await paymentClient.response('/charge', init)
// after
try {
const res = await paymentClient.response('/charge', init)
} catch (e) {
if (e instanceof NetworkError) {
console.error('Payment service unreachable:', e.message)
// retry or alert
} else throw e
} Defensive patterns
Strategy: retry
Validate before calling
const url = new URL(baseUrl) // throws immediately on malformed URL, before any request
if (!/^https?:$/.test(url.protocol)) throw new Error('Payment URL must be http(s)') Type guard
function isNetworkError(e: unknown): e is NetworkError {
return e instanceof NetworkError
} Try / catch
async function withRetry<T>(fn: () => Promise<T>, attempts = 3): Promise<T> {
for (let i = 1; ; i++) {
try { return await fn() }
catch (e) {
if (isNetworkError(e) && i < attempts) {
await new Promise(r => setTimeout(r, 2 ** i * 250)); continue
}
throw e
}
}
} Prevention
- Curl the payment service health endpoint from the same environment to verify reachability.
- Distinguish NetworkError (transport) from PaymentError (application) to decide retry vs. fix-request.
- Configure sensible connect timeouts and abort signals so requests fail fast.
- Check DNS/egress rules when deploying to new environments.
When it happens
Trigger: Any PaymentClient operation (via `response`, which calls fetchSafe) where `fetch` throws: unreachable host, wrong port, DNS resolution failure, self-signed/expired certificate, offline environment, or request aborted.
Common situations: Payment service down or redeploying, typo in the payment URL hostname, container networking/DNS issues in Kubernetes, firewall blocking egress, or a browser CORS preflight hard-failing.
Related errors
- Network error ${err}
- Network error ${err}
- response.statusText
- Network error ${error}
- platform.status.ConnectionClosed
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/9f00ddcc8b561d89.
Report an issue: GitHub.