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/fmodata version: 0.1.0-beta.34 (current main)
Summary
When using
FMServerConnectionwithuseEntityIds: 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()inpackages/fmodata/src/client/builders/table-utils.ts(line 23) still throws: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()inpackages/fmodata/src/orm/operators.tsfalls through toString(value)for non-Column, non-primitive operands. If a field created withtextField().entityId(...)is used in a filter viaeq()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
Environment
@proofkit/fmodataversion:0.1.0-beta.34(current main)