Fix error alerts showing "[object Object]" instead of the real message

FastAPI's `detail` field is a plain string for handler-raised errors, but
an array of {loc, msg, type} objects for its own automatic 422 request
validation errors. new Error(detail) silently stringified that array into
"[object Object]", hiding the actual validation failure from the user
(e.g. when adding an Odoo connection). Normalizes both shapes into one
readable message, and also guards against non-JSON error responses.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
MOHAN 2026-07-02 00:53:39 +05:30
parent 91a7c8ee80
commit f462c81efb

View File

@ -1,12 +1,41 @@
const BASE = import.meta.env.VITE_API_URL ?? 'https://odoo-mcp.thedomainnest.com';
// FastAPI's `detail` field is a plain string for handler-raised HTTPExceptions,
// but an array of {loc, msg, type} objects for its own automatic request
// validation errors (422s) — normalize both into one readable string instead
// of letting `new Error(x)` silently stringify an array/object into
// "[object Object]".
function errorDetailToMessage(detail: unknown): string {
if (typeof detail === 'string') return detail;
if (Array.isArray(detail)) {
return detail
.map((e) => {
if (e && typeof e === 'object' && 'msg' in e) {
const loc = Array.isArray((e as { loc?: unknown[] }).loc)
? (e as { loc: unknown[] }).loc.filter((p) => p !== 'body').join('.')
: '';
return loc ? `${loc}: ${(e as { msg: string }).msg}` : (e as { msg: string }).msg;
}
return String(e);
})
.join('; ');
}
return 'Request failed';
}
async function req<T>(path: string, opts?: RequestInit): Promise<T> {
const res = await fetch(`${BASE}${path}`, {
headers: { 'Content-Type': 'application/json', ...opts?.headers },
...opts,
});
const data = await res.json();
if (!res.ok) throw new Error(data.detail ?? 'Request failed');
let data: unknown;
try {
data = await res.json();
} catch {
if (!res.ok) throw new Error(`Request failed (HTTP ${res.status})`);
throw new Error('Server returned an unexpected (non-JSON) response.');
}
if (!res.ok) throw new Error(errorDetailToMessage((data as { detail?: unknown })?.detail));
return data as T;
}