XuqmGroup-RNSDK/packages/log/src/interceptor/HttpInterceptor.ts

52 行
1.5 KiB
TypeScript

/**
* HttpInterceptor wraps the global fetch to automatically report
* HTTP error responses (4xx / 5xx) through XLog.captureError.
*
* Usage:
* HttpInterceptor.start(XLog.captureError.bind(XLog))
*/
type OnError = (error: unknown, meta?: Record<string, unknown>) => void
let _originalFetch: typeof fetch | null = null
export const HttpInterceptor = {
start(onError: OnError): void {
if (_originalFetch) return // already installed
_originalFetch = global.fetch
// eslint-disable-next-line @typescript-eslint/no-explicit-any
;(global as any).fetch = async (
input: RequestInfo | URL,
init?: RequestInit,
): Promise<Response> => {
const original = _originalFetch!
try {
const res = await original(input, init)
if (!res.ok) {
const url = typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url
onError(new Error(`HTTP ${res.status} ${res.statusText}`), {
type: 'api_error',
url,
status: res.status,
})
}
return res
} catch (e) {
const url = typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url
onError(e, { type: 'api_error', url })
throw e
}
}
},
stop(): void {
if (_originalFetch) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
;(global as any).fetch = _originalFetch
_originalFetch = null
}
},
}