fix(shadcn): surface network failure reason from fetch errors

This commit is contained in:
shadcn
2026-06-10 12:12:54 +04:00
parent cef302ad5a
commit 2be26ddbb7

View File

@@ -11,11 +11,44 @@ const proxyDispatcher =
? new EnvHttpProxyAgent()
: undefined
export function fetchWithProxy(url: string | URL, init?: RequestInit) {
// The `dispatcher` option is supported by Node's fetch at runtime but
// missing from the ambient RequestInit type, hence the cast.
return fetch(url, {
...init,
dispatcher: proxyDispatcher,
} as RequestInit)
export async function fetchWithProxy(url: string | URL, init?: RequestInit) {
try {
// The `dispatcher` option is supported by Node's fetch at runtime but
// missing from the ambient RequestInit type, hence the cast.
return await fetch(url, {
...init,
dispatcher: proxyDispatcher,
} as RequestInit)
} catch (error) {
// Native fetch reports network failures as a generic "fetch failed"
// TypeError with the actual reason buried in `cause`.
if (error instanceof TypeError && error.cause) {
throw new Error(
`Request to ${url} failed, reason: ${getFailureReason(error.cause)}`,
{ cause: error.cause }
)
}
throw error
}
}
function getFailureReason(cause: unknown): string {
// Connection failures surface as an AggregateError with an empty message
// and the per-address errors (e.g. ECONNREFUSED) in `errors`.
if (cause instanceof Error && "errors" in cause) {
const errors = (cause as Error & { errors: unknown }).errors
if (Array.isArray(errors) && errors.length) {
return getFailureReason(errors[0])
}
}
if (cause instanceof Error) {
return (
cause.message ||
(cause as NodeJS.ErrnoException).code ||
"unknown error"
)
}
return String(cause)
}