mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-05-29 19:35:20 +02:00
fix(web): handle 204 No Content responses in base API service
DELETE endpoints in the automations API return 204; calling .json() on an empty body throws SyntaxError. Treat 204 as data=null and skip schema validation so callers can opt out of response bodies without errors or spurious schema-mismatch warnings. Also drops a pre-existing 'unknown → BodyInit' type error on the non-JSON body branch via a narrow cast (caller is responsible for passing a real BodyInit when Content-Type isn't application/json).
This commit is contained in:
parent
79f0218360
commit
d48bb2033b
1 changed files with 33 additions and 24 deletions
|
|
@ -1,4 +1,5 @@
|
||||||
import type { ZodType } from "zod";
|
import type { ZodType } from "zod";
|
||||||
|
import { BACKEND_URL } from "@/lib/env-config";
|
||||||
import { getClientPlatform } from "../agent-filesystem";
|
import { getClientPlatform } from "../agent-filesystem";
|
||||||
import { getBearerToken, handleUnauthorized, refreshAccessToken } from "../auth-utils";
|
import { getBearerToken, handleUnauthorized, refreshAccessToken } from "../auth-utils";
|
||||||
import {
|
import {
|
||||||
|
|
@ -9,7 +10,7 @@ import {
|
||||||
NetworkError,
|
NetworkError,
|
||||||
NotFoundError,
|
NotFoundError,
|
||||||
} from "../error";
|
} from "../error";
|
||||||
import { BACKEND_URL } from "@/lib/env-config";
|
|
||||||
enum ResponseType {
|
enum ResponseType {
|
||||||
JSON = "json",
|
JSON = "json",
|
||||||
TEXT = "text",
|
TEXT = "text",
|
||||||
|
|
@ -122,8 +123,9 @@ class BaseApiService {
|
||||||
if (contentType === "application/json" && typeof mergedOptions.body === "object") {
|
if (contentType === "application/json" && typeof mergedOptions.body === "object") {
|
||||||
fetchOptions.body = JSON.stringify(mergedOptions.body);
|
fetchOptions.body = JSON.stringify(mergedOptions.body);
|
||||||
} else {
|
} else {
|
||||||
// Pass body as-is for other content types (e.g., form data, already stringified)
|
// Pass body as-is for other content types (form data, already stringified).
|
||||||
fetchOptions.body = mergedOptions.body;
|
// Caller is responsible for passing a real BodyInit when Content-Type is not JSON.
|
||||||
|
fetchOptions.body = mergedOptions.body as BodyInit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -210,32 +212,39 @@ class BaseApiService {
|
||||||
let data;
|
let data;
|
||||||
const responseType = mergedOptions.responseType;
|
const responseType = mergedOptions.responseType;
|
||||||
|
|
||||||
try {
|
if (response.status === 204) {
|
||||||
switch (responseType) {
|
// 204 No Content has no body; .json() would throw SyntaxError.
|
||||||
case ResponseType.JSON:
|
// Leave data as null and skip schema validation below so endpoints
|
||||||
data = await response.json();
|
// that opt out of bodies (REST-style DELETE) don't error on success.
|
||||||
break;
|
data = null;
|
||||||
case ResponseType.TEXT:
|
} else {
|
||||||
data = await response.text();
|
try {
|
||||||
break;
|
switch (responseType) {
|
||||||
case ResponseType.BLOB:
|
case ResponseType.JSON:
|
||||||
data = await response.blob();
|
data = await response.json();
|
||||||
break;
|
break;
|
||||||
case ResponseType.ARRAY_BUFFER:
|
case ResponseType.TEXT:
|
||||||
data = await response.arrayBuffer();
|
data = await response.text();
|
||||||
break;
|
break;
|
||||||
// Add more cases as needed
|
case ResponseType.BLOB:
|
||||||
default:
|
data = await response.blob();
|
||||||
data = await response.json();
|
break;
|
||||||
|
case ResponseType.ARRAY_BUFFER:
|
||||||
|
data = await response.arrayBuffer();
|
||||||
|
break;
|
||||||
|
// Add more cases as needed
|
||||||
|
default:
|
||||||
|
data = await response.json();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to parse response as JSON:", error);
|
||||||
|
throw new AppError("Failed to parse response", response.status, response.statusText);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
|
||||||
console.error("Failed to parse response as JSON:", error);
|
|
||||||
throw new AppError("Failed to parse response", response.status, response.statusText);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate response
|
// Validate response
|
||||||
if (responseType === ResponseType.JSON) {
|
if (responseType === ResponseType.JSON) {
|
||||||
if (!responseSchema) {
|
if (!responseSchema || response.status === 204) {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
const parsedData = responseSchema.safeParse(data);
|
const parsedData = responseSchema.safeParse(data);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue