{"version":3,"sources":["../../src/error/parse.ts"],"sourcesContent":["import { hasText } from '@shware/utils';\nimport type { DefaultNamespace, Namespace, TFunction } from 'i18next';\nimport { type BadRequest, DetailType, type ErrorInfo } from './detail';\nimport type { ResolvedErrorReason } from './reason';\nimport type { ErrorBody } from './status';\n\nexport function getErrorInfo(data: unknown): ErrorInfo | null {\n  if (typeof data !== 'object' || data === null || !('error' in data)) return null;\n  const { error } = data as ErrorBody;\n  const errorInfo = error?.details?.find((d) => d['@type'] === DetailType.ERROR_INFO);\n  return errorInfo ?? null;\n}\n\n/**\n * @example For axios:\n *\n * const { t } = useTranslation('error');\n *\n * const { message } = getErrorMessage(error.response.data, t);\n * toast.error(message);\n */\nexport function getErrorMessage<Ns extends Namespace = DefaultNamespace, KPrefix = undefined>(\n  data: unknown,\n  t: TFunction<Ns, KPrefix>\n): { reason: ResolvedErrorReason | null; message: string } {\n  // 0. unknown error\n  if (typeof data !== 'object' || data === null || !('error' in data)) {\n    console.error('Unknown API error:', data);\n    return { reason: null, message: t('UNKNOWN') };\n  }\n\n  const { error } = data as ErrorBody;\n\n  // 1. from server via Accept-Language header or lng param\n  const localizedMessage = error?.details?.find((d) => d['@type'] === DetailType.LOCALIZED_MESSAGE);\n  if (localizedMessage) return { reason: null, message: localizedMessage.message };\n\n  // 2. from business logic error\n  const errorInfo = error?.details?.find((d) => d['@type'] === DetailType.ERROR_INFO);\n  if (errorInfo) {\n    return {\n      reason: errorInfo.reason,\n      message: t(errorInfo.reason, errorInfo.metadata),\n    };\n  }\n\n  // 3. error message in english\n  if (hasText(error.message)) return { reason: null, message: error.message };\n\n  // 4. from server via status code\n  if (error.status) return { reason: null, message: t(error.status) };\n\n  // 5. unknown error\n  console.error('Unknown API error:', data);\n  return { reason: null, message: t('UNKNOWN') };\n}\n\n/**\n * @example For react-hook-form:\n *\n * const { setError } = useForm();\n * const fieldViolations = getFieldViolations(error.response.data);\n * fieldViolations.forEach((violation) => {\n *   setError(violation.field, { message: violation.description });\n * });\n */\nexport function getFieldViolations(data: unknown): BadRequest['fieldViolations'] {\n  if (typeof data !== 'object' || data === null || !('error' in data)) return [];\n  const { error } = data as ErrorBody;\n  const badRequest = error?.details?.find((d) => d['@type'] === DetailType.BAD_REQUEST);\n  return badRequest?.fieldViolations ?? [];\n}\n"],"mappings":";AAAA,SAAS,eAAe;AAExB,SAA0B,kBAAkC;AAIrD,SAAS,aAAa,MAAiC;AAC5D,MAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,EAAE,WAAW,MAAO,QAAO;AAC5E,QAAM,EAAE,MAAM,IAAI;AAClB,QAAM,YAAY,OAAO,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,WAAW,UAAU;AAClF,SAAO,aAAa;AACtB;AAUO,SAAS,gBACd,MACA,GACyD;AAEzD,MAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,EAAE,WAAW,OAAO;AACnE,YAAQ,MAAM,sBAAsB,IAAI;AACxC,WAAO,EAAE,QAAQ,MAAM,SAAS,EAAE,SAAS,EAAE;AAAA,EAC/C;AAEA,QAAM,EAAE,MAAM,IAAI;AAGlB,QAAM,mBAAmB,OAAO,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,WAAW,iBAAiB;AAChG,MAAI,iBAAkB,QAAO,EAAE,QAAQ,MAAM,SAAS,iBAAiB,QAAQ;AAG/E,QAAM,YAAY,OAAO,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,WAAW,UAAU;AAClF,MAAI,WAAW;AACb,WAAO;AAAA,MACL,QAAQ,UAAU;AAAA,MAClB,SAAS,EAAE,UAAU,QAAQ,UAAU,QAAQ;AAAA,IACjD;AAAA,EACF;AAGA,MAAI,QAAQ,MAAM,OAAO,EAAG,QAAO,EAAE,QAAQ,MAAM,SAAS,MAAM,QAAQ;AAG1E,MAAI,MAAM,OAAQ,QAAO,EAAE,QAAQ,MAAM,SAAS,EAAE,MAAM,MAAM,EAAE;AAGlE,UAAQ,MAAM,sBAAsB,IAAI;AACxC,SAAO,EAAE,QAAQ,MAAM,SAAS,EAAE,SAAS,EAAE;AAC/C;AAWO,SAAS,mBAAmB,MAA8C;AAC/E,MAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,EAAE,WAAW,MAAO,QAAO,CAAC;AAC7E,QAAM,EAAE,MAAM,IAAI;AAClB,QAAM,aAAa,OAAO,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,WAAW,WAAW;AACpF,SAAO,YAAY,mBAAmB,CAAC;AACzC;","names":[]}