diff --git a/.changeset/rotten-spoons-reject.md b/.changeset/rotten-spoons-reject.md new file mode 100644 index 000000000..2a43f23c8 --- /dev/null +++ b/.changeset/rotten-spoons-reject.md @@ -0,0 +1,5 @@ +--- +"@solidjs/start": patch +--- + +Reject server function calls when the response is a 5xx without an X-Error header, instead of resolving with the parsed error body diff --git a/apps/tests/cypress/e2e/server-function.cy.ts b/apps/tests/cypress/e2e/server-function.cy.ts index 0bafe5c88..903758fbe 100644 --- a/apps/tests/cypress/e2e/server-function.cy.ts +++ b/apps/tests/cypress/e2e/server-function.cy.ts @@ -52,4 +52,14 @@ describe("server-function", () => { cy.visit("/generator-server-function"); cy.get("#server-fn-test").contains('¡Hola, Mundo!'); }); + it("should reject the promise when the response is a 5xx without an X-Error header", () => { + cy.intercept("POST", "/_server*", { + statusCode: 500, + headers: { "content-type": "application/json" }, + body: { statusCode: 500, statusMessage: "boom" } + }); + cy.visit("/server-function-rejected-on-500"); + cy.get("#call").click(); + cy.get("#server-fn-test").contains("rejected"); + }); }); diff --git a/apps/tests/src/routes/server-function-rejected-on-500.tsx b/apps/tests/src/routes/server-function-rejected-on-500.tsx new file mode 100644 index 000000000..3b8f99f0e --- /dev/null +++ b/apps/tests/src/routes/server-function-rejected-on-500.tsx @@ -0,0 +1,24 @@ +import { createSignal } from "solid-js"; +import { serverFnWithIsServer } from "~/functions/use-is-server"; + +export default function App() { + const [output, setOutput] = createSignal("pending"); + + const call = async () => { + try { + await serverFnWithIsServer(); + setOutput("resolved"); + } catch { + setOutput("rejected"); + } + }; + + return ( +
+ + {output()} +
+ ); +} diff --git a/packages/start/src/runtime/server-runtime.ts b/packages/start/src/runtime/server-runtime.ts index baec39ea5..ac86fe10a 100644 --- a/packages/start/src/runtime/server-runtime.ts +++ b/packages/start/src/runtime/server-runtime.ts @@ -88,8 +88,8 @@ async function fetchServerFunction( result = await deserializeJSONStream(cloned); } } - if (response.headers.has("X-Error")) { - throw result; + if (response.headers.has("X-Error") || response.status >= 500) { + throw result ?? new Error(`Server function call failed with status ${response.status}`); } return result; }