improve generic error validation messages

This commit is contained in:
Josh Hawkins 2026-01-25 18:47:31 -06:00
parent dd0c497fd3
commit f534c7216a
5 changed files with 16 additions and 21 deletions

View File

@ -68,10 +68,10 @@ export function ConfigForm({
formContext,
i18nNamespace,
}: ConfigFormProps) {
const { t } = useTranslation([
const { t, i18n } = useTranslation([
i18nNamespace || "common",
"views/settings",
"validation",
"config/validation",
]);
const [showAdvanced, setShowAdvanced] = useState(false);
@ -117,7 +117,7 @@ export function ConfigForm({
);
// Create error transformer for user-friendly error messages
const errorTransformer = useMemo(() => createErrorTransformer(t), [t]);
const errorTransformer = useMemo(() => createErrorTransformer(i18n), [i18n]);
const handleChange = useCallback(
(e: IChangeEvent) => {

View File

@ -2,7 +2,7 @@
// Maps JSON Schema validation keywords to user-friendly messages
import type { ErrorTransformer } from "@rjsf/utils";
import type { TFunction } from "i18next";
import type { i18n as I18n } from "i18next";
export interface ErrorMessageMap {
[keyword: string]: string | ((params: Record<string, unknown>) => string);
@ -51,7 +51,9 @@ export const defaultErrorMessages: ErrorMessageMap = {
* Creates an error transformer function for RJSF
* Transforms technical JSON Schema errors into user-friendly messages
*/
export function createErrorTransformer(t: TFunction): ErrorTransformer {
export function createErrorTransformer(i18n: I18n): ErrorTransformer {
const t = i18n.t.bind(i18n);
const getDefaultMessage = (
errorType: string,
params: Record<string, unknown>,
@ -117,31 +119,22 @@ export function createErrorTransformer(t: TFunction): ErrorTransformer {
let message: string | undefined;
const missingTranslation = "__missing_translation__";
// Try field-specific validation message first
if (fieldPath) {
const fieldKey = `${fieldPath}.validation.${errorType}`;
const translated = t(fieldKey, {
...normalizedParams,
ns: ["config"],
defaultValue: missingTranslation,
});
if (translated !== fieldKey && translated !== missingTranslation) {
message = translated;
if (i18n.exists(fieldKey)) {
message = t(fieldKey, normalizedParams);
}
}
// Fall back to generic validation message
if (!message) {
const genericKey = errorType;
const translated = t(genericKey, {
...normalizedParams,
ns: ["validation"],
defaultValue: missingTranslation,
});
if (translated !== genericKey && translated !== missingTranslation) {
message = translated;
if (i18n.exists(genericKey, { ns: "config/validation" })) {
message = t(genericKey, {
...normalizedParams,
ns: ["config/validation"],
});
}
}

View File

@ -72,6 +72,7 @@ i18n
"config/semantic_search",
"config/face_recognition",
"config/lpr",
"config/validation",
],
defaultNS: "common",

View File

@ -95,6 +95,7 @@ const globalSectionConfigs: Record<
"tls_client_key",
"tls_insecure",
],
liveValidate: true,
},
database: {
i18nNamespace: "config/database",