Skip to content

Commit 3584bff

Browse files
author
Chris Corsi
committed
fix(fmodata): handle missing Location header in batch insert sub-responses
FileMaker batch sub-responses may not include the Location header that standalone responses provide. Instead of throwing InvalidLocationHeaderError, return ROWID -1 when the header is absent in a batch context. This fixes the follow-up issue from #207 where batch writes (INSERT/UPDATE) failed with InvalidLocationHeaderError after the URL fix.
1 parent b075656 commit 3584bff

2 files changed

Lines changed: 11 additions & 13 deletions

File tree

.changeset/fix-batch-sub-request-urls.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
"@proofkit/fmodata": patch
33
---
44

5-
Fix batch sub-request URLs to use canonical FileMaker OData path format. Strips the Otto proxy prefix (`/otto/`) and `.fmp12` file extension from database names in sub-request URLs inside multipart batch bodies, which are processed directly by FileMaker's OData engine.
5+
Fix batch sub-request URLs to use canonical FileMaker OData path format. Strips the Otto proxy prefix (`/otto/`) and `.fmp12` file extension from database names in sub-request URLs inside multipart batch bodies, which are processed directly by FileMaker's OData engine. Also fix `InvalidLocationHeaderError` in batch insert/update sub-responses by gracefully handling missing Location headers (returns ROWID -1 instead of throwing).

packages/fmodata/src/client/insert-builder.ts

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -275,14 +275,9 @@ export class InsertBuilder<
275275
// Check for Location header (for return=minimal)
276276
if (this.returnPreference === "minimal") {
277277
const locationHeader = getLocationHeader(response.headers);
278-
if (locationHeader) {
279-
const rowid = this.parseLocationHeader(locationHeader);
280-
// biome-ignore lint/suspicious/noExplicitAny: Type assertion for generic return type
281-
return { data: { ROWID: rowid } as any, error: undefined };
282-
}
283-
throw new InvalidLocationHeaderError(
284-
"Location header is required when using return=minimal but was not found in response",
285-
);
278+
const rowid = locationHeader ? this.parseLocationHeader(locationHeader) : -1;
279+
// biome-ignore lint/suspicious/noExplicitAny: Type assertion for generic return type
280+
return { data: { ROWID: rowid } as any, error: undefined };
286281
}
287282

288283
// For 204 responses without return=minimal, FileMaker doesn't return the created entity
@@ -295,11 +290,14 @@ export class InsertBuilder<
295290
};
296291
}
297292

298-
// If we expected return=minimal but got a body, that's unexpected
293+
// If we expected return=minimal but got a body (e.g. batch sub-responses
294+
// where FM returns 204-with-body, converted to 200 by parsedToResponse),
295+
// try to extract ROWID from the Location header or return -1.
299296
if (this.returnPreference === "minimal") {
300-
throw new InvalidLocationHeaderError(
301-
"Expected 204 No Content for return=minimal, but received response with body",
302-
);
297+
const locationHeader = getLocationHeader(response.headers);
298+
const rowid = locationHeader ? this.parseLocationHeader(locationHeader) : -1;
299+
// biome-ignore lint/suspicious/noExplicitAny: Type assertion for generic return type
300+
return { data: { ROWID: rowid } as any, error: undefined };
303301
}
304302

305303
// Use safeJsonParse to handle FileMaker's invalid JSON with unquoted ? values

0 commit comments

Comments
 (0)