import { TFunction } from "i18next"; import { Alert } from "react-bootstrap"; import { Trans, useTranslation } from "react-i18next"; import { ApiError, ErrorCode, ValidationError, validationErrorType, ValidationErrorType, } from "~/lib/api/error"; export default function ErrorAlert({ error }: { error: ApiError }) { const { t } = useTranslation(); return ( {t("error.heading")} {errorCodeDesc(t, error.code)} {error.errors && ( )} ); } function ValidationErrors({ errorKey, errors }: { errorKey: string; errors: ValidationError[] }) { return (
  • {errorKey} :
  • ); } function ValidationErrorEntry({ error }: { error: ValidationError }) { const { t } = useTranslation(); const { min_length: minLength, max_length: maxLength, actual_length: actualLength, message: reason, actual_value: actualValue, allowed_values: allowedValues, } = error; switch (validationErrorType(error)) { case ValidationErrorType.LengthError: if (error.actual_length! > error.max_length!) { return ( Value is too long, maximum length is {{ maxLength }}, current length is{" "} {{ actualLength }}. ); } if (error.actual_length! < error.min_length!) { return ( Value is too short, minimum length is {{ minLength }}, current length is{" "} {{ actualLength }}. ); } break; case ValidationErrorType.DisallowedValueError: return ( v.toString()).join(", "), }} > {/* @ts-expect-error i18next handles interpolation */} The value {{ actualValue }} is not allowed here. Allowed values are:{" "} {/* @ts-expect-error i18next handles interpolation */} {{ allowedValues }} ); default: if (error.actual_value) { return ( {/* @ts-expect-error i18next handles interpolation */} The value {{ actualValue }} is not allowed here. Reason: {{ reason }} ); } return <>{t("error.validation.generic-no-value", { reason: error.message })}; } } export const errorCodeDesc = (t: TFunction, code: ErrorCode) => { switch (code) { case ErrorCode.AuthenticationError: return t("error.errors.authentication-error"); case ErrorCode.AuthenticationRequired: return t("error.errors.authentication-required"); case ErrorCode.BadRequest: return t("error.errors.bad-request"); case ErrorCode.Forbidden: return t("error.errors.forbidden"); case ErrorCode.GenericApiError: return t("error.errors.generic-error"); case ErrorCode.InternalServerError: return t("error.errors.internal-server-error"); case ErrorCode.MemberNotFound: return t("error.errors.member-not-found"); case ErrorCode.UserNotFound: return t("error.errors.user-not-found"); case ErrorCode.AccountAlreadyLinked: return t("error.errors.account-already-linked"); } return t("error.errors.generic-error"); };