@@ -5,6 +5,11 @@ export { format } from './sanitization.js'
55export { hex } from './text.js'
66import { Version } from './version.js'
77
8+ // Cloudflare Workers sets navigator.userAgent to 'Cloudflare-Workers' when the
9+ // global_navigator compatibility flag is enabled (default since 2022-03-21).
10+ // https://developers.cloudflare.com/workers/configuration/compatibility-flags/#global-navigator
11+ const isCloudflareWorker = typeof navigator !== 'undefined' && navigator . userAgent === 'Cloudflare-Workers'
12+
813type Row < T extends ExecuteAs = 'object' > = T extends 'array' ? any [ ] : T extends 'object' ? Record < string , any > : never
914
1015interface VitessError {
@@ -367,10 +372,21 @@ async function postJSON<T>(config: Config, fetch: Fetch, url: string | URL, body
367372 headers
368373 }
369374
370- throw new UnknownError (
371- `Expected a JSON response from the database API but received: HTTP ${ response . status } ${ response . statusText } ` ,
372- context
373- )
375+ // Cloudflare uses HTTP 520-530 for its own errors. These are never from the database API.
376+ // https://developers.cloudflare.com/support/troubleshooting/cloudflare-errors/troubleshooting-cloudflare-5xx-errors/
377+ const isCloudflareStatusCode = response . status >= 520 && response . status <= 530
378+
379+ // Inside a Worker, any non-JSON response is from Cloudflare's infrastructure,
380+ // since the database API exclusively returns JSON responses.
381+ const isCloudflareError = isCloudflareStatusCode || isCloudflareWorker
382+
383+ const status = response . statusText ? `${ response . status } ${ response . statusText } ` : `${ response . status } `
384+
385+ const message = isCloudflareError
386+ ? `Cloudflare error: HTTP ${ status } (not a database error)`
387+ : `Expected JSON response from database API, got HTTP ${ status } `
388+
389+ throw new UnknownError ( message , context )
374390}
375391
376392export function connect ( config : Config ) : Connection {
0 commit comments