fix(ar1-admin): crash su error Pydantic (detail array) -> formatErrorDetail helper
Bug: click 'Crea versione' con version vuota o invalida -> pagina bianca + 'error'.
Causa: il BE restituisce 422 con detail come ARRAY Pydantic [{loc, msg, type}].
Il codice faceva detail: err?.detail || 'fallback' -> array passato a PrimeReact Toast
-> React render 'Objects are not valid as a React child' -> crash unhandled.
Fix: helper formatErrorDetail(detail, fallback) che normalizza:
- string -> ritorna direttamente
- array Pydantic -> 'loc.loc: msg; loc.loc: msg' (filtrato 'body')
- object -> JSON.stringify
- altro -> String(x)
Applicato con regex a tutti i pattern 'err?.detail || "fallback"' nel file (tutti
i toast show di errore nei vari handler: saveLayout, saveNewVersion, savePolicy,
savePecRule, deletePecRule, saveEmail, runPreview, runBulk, loadXxx).
This commit is contained in:
@@ -58,8 +58,24 @@ const PEC_KIND_OPTIONS = [
|
|||||||
{ label: PEC_KIND_LABEL.AR1_BULK_MANUAL, value: 'AR1_BULK_MANUAL' }
|
{ label: PEC_KIND_LABEL.AR1_BULK_MANUAL, value: 'AR1_BULK_MANUAL' }
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
// Normalizza il campo detail che puo essere string o array Pydantic [{loc, msg, type}]
|
||||||
|
const formatErrorDetail = (detail, fallback) => {
|
||||||
|
if (!detail) return fallback || 'Errore';
|
||||||
|
if (typeof detail === 'string') return detail;
|
||||||
|
if (Array.isArray(detail)) {
|
||||||
|
return detail.map(e => {
|
||||||
|
const loc = Array.isArray(e.loc) ? e.loc.filter(x => x !== 'body').join('.') : '';
|
||||||
|
const msg = e.msg || e.message || JSON.stringify(e);
|
||||||
|
return loc ? `${loc}: ${msg}` : msg;
|
||||||
|
}).join('; ');
|
||||||
|
}
|
||||||
|
if (typeof detail === 'object') return JSON.stringify(detail);
|
||||||
|
return String(detail);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ar1AdminConfig — configurazione AR1 per superadmin. (build 1776950454)
|
* Ar1AdminConfig — configurazione AR1 per superadmin. (build 1776950637)
|
||||||
* URL: /ar1-admin
|
* URL: /ar1-admin
|
||||||
*
|
*
|
||||||
* 5 sezioni (TabView):
|
* 5 sezioni (TabView):
|
||||||
@@ -163,19 +179,19 @@ const Ar1AdminConfig = () => {
|
|||||||
setLoadingTpl(true);
|
setLoadingTpl(true);
|
||||||
Ar1Service.listTemplates(
|
Ar1Service.listTemplates(
|
||||||
(resp) => { setTemplates(resp?.items || resp || []); setLoadingTpl(false); },
|
(resp) => { setTemplates(resp?.items || resp || []); setLoadingTpl(false); },
|
||||||
(err) => { setLoadingTpl(false); if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: err?.detail || 'Caricamento template fallito' }); }
|
(err) => { setLoadingTpl(false); if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: formatErrorDetail(err?.detail, 'Caricamento template fallito') }); }
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
const loadPolicy = () => {
|
const loadPolicy = () => {
|
||||||
Ar1Service.getPolicy(
|
Ar1Service.getPolicy(
|
||||||
(resp) => { setPolicy(resp); setPolicyDraft(resp); },
|
(resp) => { setPolicy(resp); setPolicyDraft(resp); },
|
||||||
(err) => { if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: err?.detail || 'Caricamento policy fallito' }); }
|
(err) => { if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: formatErrorDetail(err?.detail, 'Caricamento policy fallito') }); }
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
const loadPecRules = () => {
|
const loadPecRules = () => {
|
||||||
Ar1Service.listPecSchedule(
|
Ar1Service.listPecSchedule(
|
||||||
(resp) => setPecRules(resp?.items || resp || []),
|
(resp) => setPecRules(resp?.items || resp || []),
|
||||||
(err) => { if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: err?.detail || 'Caricamento regole fallito' }); }
|
(err) => { if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: formatErrorDetail(err?.detail, 'Caricamento regole fallito') }); }
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
const loadDocCategories = () => {
|
const loadDocCategories = () => {
|
||||||
@@ -192,7 +208,7 @@ const Ar1AdminConfig = () => {
|
|||||||
setAvailableVariables(resp?.available_variables || []);
|
setAvailableVariables(resp?.available_variables || []);
|
||||||
setLoadingEmail(false);
|
setLoadingEmail(false);
|
||||||
},
|
},
|
||||||
(err) => { setLoadingEmail(false); if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: err?.detail || 'Caricamento testi fallito' }); }
|
(err) => { setLoadingEmail(false); if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: formatErrorDetail(err?.detail, 'Caricamento testi fallito') }); }
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -268,7 +284,7 @@ const Ar1AdminConfig = () => {
|
|||||||
setEditLayoutOpen(false);
|
setEditLayoutOpen(false);
|
||||||
loadTemplates();
|
loadTemplates();
|
||||||
},
|
},
|
||||||
(err) => { if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: err?.detail || 'Salvataggio fallito' }); }
|
(err) => { if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: formatErrorDetail(err?.detail, 'Salvataggio fallito') }); }
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -292,7 +308,7 @@ const Ar1AdminConfig = () => {
|
|||||||
setNewVersionOpen(false);
|
setNewVersionOpen(false);
|
||||||
loadTemplates();
|
loadTemplates();
|
||||||
},
|
},
|
||||||
(err) => { if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: err?.detail || 'Creazione fallita' }); }
|
(err) => { if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: formatErrorDetail(err?.detail, 'Creazione fallita') }); }
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -319,7 +335,7 @@ const Ar1AdminConfig = () => {
|
|||||||
},
|
},
|
||||||
(err) => {
|
(err) => {
|
||||||
setSavingPolicy(false);
|
setSavingPolicy(false);
|
||||||
if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: err?.detail || 'Salvataggio fallito' });
|
if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: formatErrorDetail(err?.detail, 'Salvataggio fallito') });
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -353,7 +369,7 @@ const Ar1AdminConfig = () => {
|
|||||||
setPecDialogOpen(false);
|
setPecDialogOpen(false);
|
||||||
loadPecRules();
|
loadPecRules();
|
||||||
};
|
};
|
||||||
const onKo = (err) => { if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: err?.detail || 'Salvataggio fallito' }); };
|
const onKo = (err) => { if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: formatErrorDetail(err?.detail, 'Salvataggio fallito') }); };
|
||||||
if (pecEditing) Ar1Service.updatePecRule(pecEditing.id, payload, onOk, onKo);
|
if (pecEditing) Ar1Service.updatePecRule(pecEditing.id, payload, onOk, onKo);
|
||||||
else Ar1Service.createPecRule(payload, onOk, onKo);
|
else Ar1Service.createPecRule(payload, onOk, onKo);
|
||||||
};
|
};
|
||||||
@@ -372,7 +388,7 @@ const Ar1AdminConfig = () => {
|
|||||||
if (toast.current) toast.current.show({ severity: 'success', summary: 'Eliminata', detail: 'Regola eliminata' });
|
if (toast.current) toast.current.show({ severity: 'success', summary: 'Eliminata', detail: 'Regola eliminata' });
|
||||||
loadPecRules();
|
loadPecRules();
|
||||||
},
|
},
|
||||||
(err) => { if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: err?.detail || 'Eliminazione fallita' }); }
|
(err) => { if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: formatErrorDetail(err?.detail, 'Eliminazione fallita') }); }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -400,7 +416,7 @@ const Ar1AdminConfig = () => {
|
|||||||
},
|
},
|
||||||
(err) => {
|
(err) => {
|
||||||
setBulkRunning(false);
|
setBulkRunning(false);
|
||||||
if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: err?.detail || 'Invio fallito' });
|
if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: formatErrorDetail(err?.detail, 'Invio fallito') });
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -433,7 +449,7 @@ const Ar1AdminConfig = () => {
|
|||||||
setEditEmailOpen(false);
|
setEditEmailOpen(false);
|
||||||
loadEmailTemplates();
|
loadEmailTemplates();
|
||||||
},
|
},
|
||||||
(err) => { if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: err?.detail || 'Salvataggio fallito' }); }
|
(err) => { if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: formatErrorDetail(err?.detail, 'Salvataggio fallito') }); }
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -444,7 +460,7 @@ const Ar1AdminConfig = () => {
|
|||||||
setPreviewSubject(resp.subject);
|
setPreviewSubject(resp.subject);
|
||||||
setPreviewHtml(resp.body_html);
|
setPreviewHtml(resp.body_html);
|
||||||
},
|
},
|
||||||
(err) => { if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: err?.detail || 'Anteprima fallita' }); }
|
(err) => { if (toast.current) toast.current.show({ severity: 'error', summary: 'Errore', detail: formatErrorDetail(err?.detail, 'Anteprima fallita') }); }
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user