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 && (
{error.errors.map((e, i) => (
))}
)}
);
}
function ValidationErrors({ errorKey, errors }: { errorKey: string; errors: ValidationError[] }) {
return (
{errorKey}
:
{errors.map((e, i) => (
-
))}
);
}
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");
};