XuqmGroup-RNSDK/packages/common/src/api/diagnostics.ts

91 行
2.5 KiB
TypeScript

2026-07-18 08:35:36 +08:00
import type { AxiosError, AxiosResponse } from 'axios'
import { isAxiosError } from 'axios'
2026-07-18 08:35:36 +08:00
import type { z } from 'zod'
import type { RequestError } from './errors'
2026-07-18 08:35:36 +08:00
type SafeIssue = {
code: string
message: string
path: string
}
export type SafeApiDiagnostic = {
code?: string
httpStatus?: number
issues?: SafeIssue[]
method?: string
path?: string
type: 'AxiosError' | 'Response' | 'ValidationError'
}
export type SafeApiErrorReport = {
diagnostic?: SafeApiDiagnostic
requestType: RequestError['type']
}
2026-07-18 08:35:36 +08:00
/**
* / bodyheaders URL
* userIdsessionId
*/
function requestShape(response: AxiosResponse<unknown>) {
return {
httpStatus: response.status,
method: response.config.method?.toUpperCase(),
path: response.config.url,
}
}
export function createResponseDiagnostic(response: AxiosResponse<unknown>): SafeApiDiagnostic {
return { type: 'Response', ...requestShape(response) }
}
export function createValidationDiagnostic(
response: AxiosResponse<unknown>,
issues: z.ZodIssue[],
): SafeApiDiagnostic {
return {
type: 'ValidationError',
...requestShape(response),
issues: issues.map(issue => ({
code: issue.code,
message: issue.message,
path: issue.path.join('.'),
})),
}
}
export function createAxiosDiagnostic(error: AxiosError): SafeApiDiagnostic {
return {
type: 'AxiosError',
code: error.code,
httpStatus: error.response?.status,
method: error.config?.method?.toUpperCase(),
path: error.config?.url,
}
}
type ValidationCause = {
issues: z.ZodIssue[]
response: AxiosResponse<unknown>
}
function isValidationCause(value: unknown): value is ValidationCause {
if (!value || typeof value !== 'object') return false
const candidate = value as Partial<ValidationCause>
return Array.isArray(candidate.issues) && Boolean(candidate.response?.config)
}
/**
* RequestError.cause
* cause Axios configheaders
*/
export function createSafeApiErrorReport(error: RequestError): SafeApiErrorReport {
const cause = error.cause
const diagnostic = isValidationCause(cause)
? createValidationDiagnostic(cause.response, cause.issues)
: isAxiosError(cause)
? createAxiosDiagnostic(cause)
: undefined
return { diagnostic, requestType: error.type }
}