fix(grid): show real save error message instead of [object Object]

This commit is contained in:
zipg authored and GitHub committed 2026-09-17 01:38:13 +08:00
1 parent 2dfd4e0058
commit 5f5a78a044
3 files changed
+48 -3

No files matched your search

+4 -2
View File
@@ -283,9 +283,11 @@ export function formatError(e: unknown): string {
}
}
// Fallback: attempt to stringify
// Fallback: prefer bounded nested text (message/reason/detail, .error/.backendError)
// over raw string coercion so object-shaped failures never degrade to "[object Object]".
const fallback = boundedFallbackText(e);
try {
return sanitizeBackendErrorMessage(String(e));
return sanitizeBackendErrorMessage(fallback ?? String(e));
} catch {
return "Unknown error occurred";
}
@@ -0,0 +1,35 @@
import { describe, expect, it } from "vitest";
import { normalizeDataGridSaveError } from "@/lib/dataGrid/dataGridSql";
describe("normalizeDataGridSaveError", () => {
it("extracts a message from an object-shaped save failure", () => {
expect(normalizeDataGridSaveError("mysql", { message: "Duplicate entry for key id" })).toBe("Duplicate entry for key id");
});
it("extracts messages from nested backend request errors", () => {
expect(normalizeDataGridSaveError("mysql", { error: { message: "Column count does not match" } })).toBe("Column count does not match");
});
it("keeps Error messages and database-specific guidance intact", () => {
expect(normalizeDataGridSaveError("mysql", new Error("save failed"))).toBe("save failed");
expect(normalizeDataGridSaveError("hive", new Error("Error 10294: update is disabled"))).toContain("Hive UPDATE/DELETE");
});
it("prefers the Error message over a backend envelope without detail", () => {
const sqlError = Object.assign(new Error("Duplicate entry '1' for key 'PRIMARY'"), {
backendError: {
version: 1,
code: "DBX-JDBC-4001",
messageKey: "backendErrors.jdbc.sqlFailed",
messageParams: { stage: "execute" },
source: "jdbc_agent",
operationOutcome: "unknown",
},
});
expect(normalizeDataGridSaveError("mysql", sqlError)).toBe("Duplicate entry '1' for key 'PRIMARY'");
});
it("extracts messages from nested backendError envelopes", () => {
expect(normalizeDataGridSaveError("mysql", { backendError: { message: "Connection refused" } })).toBe("Connection refused");
});
});
+9 -1
View File
@@ -1,5 +1,6 @@
import type { DatabaseType } from "@/types/database";
import * as api from "@/lib/backend/api";
import { formatError } from "@/lib/backend/errorUtils";
export type GridCellValue = string | number | boolean | null | unknown[] | { [key: string]: unknown };
@@ -167,8 +168,15 @@ export function buildHiveTablePropertiesSql(options: HiveTablePropertiesSqlOptio
return api.buildHiveTablePropertiesSql(options);
}
function formatDataGridSaveError(error: unknown): string {
if (error instanceof Error && error.message) {
return error.message;
}
return formatError(error);
}
export function normalizeDataGridSaveError(databaseType: DatabaseType | undefined, error: unknown): string {
const message = error instanceof Error ? error.message : String(error);
const message = formatDataGridSaveError(error);
if ((databaseType === "hive" || databaseType === "argo") && /Attempt to do update or delete|Error 10294/i.test(message)) {
return "Hive UPDATE/DELETE are not enabled for this table or server. Add rows with INSERT, or enable ACID transactional tables in Hive before editing/deleting existing rows.";
}