81 lines
2.3 KiB
TypeScript
81 lines
2.3 KiB
TypeScript
export interface FullDomainError {
|
|
title: string
|
|
message?: string
|
|
detail?: string
|
|
source?: {
|
|
pointer: string
|
|
parameter: string
|
|
}
|
|
}
|
|
|
|
export type ShortDomainError = FullDomainError['title']
|
|
|
|
export interface BaseDomainError {
|
|
base: ShortDomainError[]
|
|
}
|
|
|
|
export interface ErrorListResponse {
|
|
errors: BaseDomainError | FullDomainError[] | ShortDomainError[]
|
|
}
|
|
|
|
export interface SingleErrorResponse {
|
|
error: ShortDomainError
|
|
}
|
|
|
|
export type ErrorResponse = ErrorListResponse | SingleErrorResponse
|
|
|
|
export type ErrorPayload<T = unknown> = {
|
|
body: ErrorResponse
|
|
statusCode: number
|
|
responseData?: T | null
|
|
}
|
|
|
|
export type MaybeError = ShortDomainError | FullDomainError | undefined
|
|
|
|
export const buildUnknownError = (statusCode: number) => `Unknown Error occurred from Server with status code ${statusCode}`
|
|
|
|
export class ApiError<T = unknown> extends Error {
|
|
readonly body: ErrorResponse
|
|
readonly statusCode: number
|
|
readonly responseData: T | null
|
|
constructor(payload: ErrorPayload<T>) {
|
|
super('Caught an error while fetching the API Server endpoint...')
|
|
this.name = 'ApiError'
|
|
this.body = payload.body
|
|
this.statusCode = payload.statusCode
|
|
this.responseData = payload?.responseData || null
|
|
}
|
|
}
|
|
|
|
export function isErrorResponse<R>(data: R | ErrorResponse): data is ErrorResponse {
|
|
return isSingleErrorResponse<R>(data) || isErrorListResponse<R>(data)
|
|
}
|
|
|
|
export function isSingleErrorResponse<R>(data: R | ErrorResponse): data is SingleErrorResponse {
|
|
return typeof data === 'object' && data !== null && 'error' in data
|
|
}
|
|
|
|
export function isErrorListResponse<R>(data: R | ErrorResponse): data is ErrorListResponse {
|
|
return typeof data === 'object' && data !== null && 'errors' in data
|
|
}
|
|
|
|
export function isShortDomainError(error: MaybeError): error is ShortDomainError {
|
|
return typeof error === 'string'
|
|
}
|
|
|
|
export function extractErrorMessage(apiError: ApiError): string {
|
|
const body = isSingleErrorResponse(apiError.body) ? [apiError.body.error] : apiError.body.errors
|
|
const errors = Array.isArray(body) ? body : body.base
|
|
const firstError = errors.at(0)
|
|
if (firstError === undefined) {
|
|
return buildUnknownError(apiError.statusCode)
|
|
}
|
|
if (isShortDomainError(firstError)) {
|
|
return firstError
|
|
}
|
|
if ('message' in firstError && firstError.message) {
|
|
return firstError.message
|
|
}
|
|
return firstError.title
|
|
}
|