i18n
Okapi provides English titles and messages by default. Pass i18n options to a mapper factory or core mapping function to replace them with static translations or resolve them at runtime.
import { createAxiosErrorMapper } from '@alexovn/okapi/axios'
const mapAxiosError = createAxiosErrorMapper({
i18n: {
titles: { network: 'Connection problem' },
messages: { network: 'Check your internet connection and try again.' },
},
})The same i18n object is available through the shared OkapiErrorOptions, MapOkapiErrorOptions, and OkapiErrorAdapterOptions types. See Types.
Types
OkapiErrorI18nOptions
Options for customizing mapped error titles and messages.
interface OkapiErrorI18nOptions<
TCustomKind extends string = never,
TValidationErrors = ApiValidationErrors,
> {
titles?: OkapiErrorTitles<TCustomKind>
statusTitles?: OkapiErrorStatusTitles
messages?: OkapiErrorMessages<TCustomKind>
statusMessages?: OkapiErrorStatusMessages
resolveTitle?: OkapiErrorTitleResolver<TCustomKind, TValidationErrors>
resolveMessage?: OkapiErrorMessageResolver<TCustomKind, TValidationErrors>
}Static Translations
Use static translations when the translated strings are known while configuring the mapper. Kind-based values provide general copy for an error category; status-based values override that copy for a specific HTTP response.
titles
Custom titles keyed by built-in or application-specific error kind.
- Type:
type OkapiErrorTitles<TCustomKind extends string = never> = Partial<
Record<OkapiErrorKind<TCustomKind>, string>
>statusTitles
Custom titles keyed by HTTP status code.
- Type:
type OkapiErrorStatusTitles = Partial<Record<number, string>>messages
Custom messages keyed by built-in or application-specific error kind.
- Type:
type OkapiErrorMessages<TCustomKind extends string = never> = Partial<
Record<OkapiErrorKind<TCustomKind>, string>
>statusMessages
Custom messages keyed by HTTP status code.
- Type:
type OkapiErrorStatusMessages = Partial<Record<number, string>>Example
import type { OkapiErrorAdapterOptions } from '@alexovn/okapi'
const options: OkapiErrorAdapterOptions = {
i18n: {
titles: {
'not-found': 'Not found',
network: 'Connection problem',
},
statusTitles: {
503: 'Temporarily unavailable',
},
messages: {
'not-found': 'The requested resource was not found.',
network: 'Check your internet connection and try again.',
},
statusMessages: {
503: 'The service is temporarily unavailable. Please try again later.',
},
},
}Dynamic Translations
Use resolvers when translation depends on runtime data or an i18n library. Each resolver receives the complete normalized OkapiError, including its kind, source, statusCode, raw response, and original cause.
resolveTitle
A function that derives a custom title from a normalized error.
- Type:
type OkapiErrorTitleResolver<
TCustomKind extends string = never,
TValidationErrors = ApiValidationErrors,
> = (error: OkapiError<TCustomKind, TValidationErrors>) => string | undefinedresolveMessage
A function that derives a custom message from a normalized error.
- Type:
type OkapiErrorMessageResolver<
TCustomKind extends string = never,
TValidationErrors = ApiValidationErrors,
> = (error: OkapiError<TCustomKind, TValidationErrors>) => string | undefinedExample
import type { OkapiErrorAdapterOptions } from '@alexovn/okapi'
const options: OkapiErrorAdapterOptions = {
i18n: {
resolveTitle: ({ statusCode }) => {
if (statusCode === 503) {
return 'Temporarily unavailable'
}
return undefined
},
resolveMessage: ({ kind, statusCode }) => {
if (statusCode !== undefined) {
return translate(`errors.http.${statusCode}`)
}
return translate(`errors.api.${kind}`)
},
},
}Translation Resolution Order
Titles are resolved in this order:
i18n.resolveTitlei18n.statusTitles[statusCode]i18n.titles[kind]- Built-in title
Messages are resolved in this order:
i18n.resolveMessagei18n.statusMessages[statusCode]i18n.messages[kind]- Built-in message
A resolver can return
undefinedto continue to the next fallback.