-
Notifications
You must be signed in to change notification settings - Fork 3
Description
Summary
When using FMServerConnection with useEntityIds: true, two error scenarios produce inconsistent or unhelpful behavior compared to other error paths (bad credentials, unreachable server, missing record, etc.), which all correctly return { data, error } tuples.
Status (verified against v0.1.0-beta.34 on main)
Both issues are still present as of the current codebase.
Issue 1: Non-existent table throws instead of returning { error }
resolveTableId() in packages/fmodata/src/client/builders/table-utils.ts (line 23) still throws:
throw new Error(`useEntityIds is true but table "${getTableName(table)}" does not have entity IDs configured`);
Call sites (url-builder.ts, query-builder.ts) don't catch this, so .execute() throws instead of returning { error }.
Expected: .execute() should return { error } like all other error conditions.
Issue 2: Standalone field reference in eq() serializes as [object Object]
_operandToString() in packages/fmodata/src/orm/operators.ts falls through to String(value) for non-Column, non-primitive operands. If a field created with textField().entityId(...) is used in a filter via eq() without being part of a table schema, it serializes as [object Object] in the OData URL.
Expected: Either validate at URL-build time that the field reference is resolvable, or catch this at the type level so eq() only accepts fields from a defined table schema.
Reproduction
import { FMServerConnection, fmTableOccurrence, textField, eq } from "@proofkit/fmodata";
const connection = new FMServerConnection({ serverUrl: "...", auth: { username: "...", password: "..." } });
const db = connection.database("SomeFile.fmp12", { useEntityIds: true });
// Issue 1: throws instead of returning { error }
const FakeTable = fmTableOccurrence("NonExistent", {
id: textField().primaryKey().entityId("FMFID:999999999"),
});
const result1 = await db.from(FakeTable).list().execute(); // throws!
// Issue 2: [object Object] in URL
const looseField = textField().entityId("FMFID:000000001");
const result2 = await db.from(RealTable).list().where(eq(looseField, "test")).execute();
// sends: $filter=[object Object] eq 'test'Environment
@proofkit/fmodataversion:0.1.0-beta.34(current main)