diff --git a/packages/next-drupal/src/client.ts b/packages/next-drupal/src/client.ts index d355f532..7661a30f 100644 --- a/packages/next-drupal/src/client.ts +++ b/packages/next-drupal/src/client.ts @@ -673,6 +673,19 @@ export class DrupalClient { withAuth: options.withAuth, }) + // Server error. But 404 is treated implicitely below. + if (!response?.ok && response.status !== 404) { + let errorMessage: string + try { + const responseJson = await response.json() + errorMessage = `${response.status} ${responseJson?.message}` + } catch (e) { + /* c8 ignore next 2 */ + errorMessage = `${response.status} ${response.statusText}` + } + throw new Error(errorMessage) + } + const json = await response.json() if (!json?.["resolvedResource#uri{0}"]?.body) { @@ -890,10 +903,21 @@ export class DrupalClient { }) if (!response?.ok) { - // Do not throw errors here. - // Otherwise next.js will catch error and throw a 500. - // We want a 404. - return null + // Do not throw errors here when response is 404. + if (response.status === 404) { + return null + } + + // Throw error in any other situation as response is not ok. + let errorMessage: string + try { + const responseJson = await response.json() + errorMessage = `${response.status} ${responseJson?.message}` + } catch (e) { + /* c8 ignore next 2 */ + errorMessage = `${response.status} ${response.statusText}` + } + throw new Error(errorMessage) } const json = await response.json() diff --git a/packages/next-drupal/tests/DrupalClient/resource-methods.test.ts b/packages/next-drupal/tests/DrupalClient/resource-methods.test.ts index 51fc43b1..2335edc9 100644 --- a/packages/next-drupal/tests/DrupalClient/resource-methods.test.ts +++ b/packages/next-drupal/tests/DrupalClient/resource-methods.test.ts @@ -449,6 +449,19 @@ describe("getResourceByPath()", () => { ).rejects.toThrow("Unable to resolve path /path-do-not-exist.") }) + test("throws an error for server errors", async () => { + const client = new DrupalClient(BASE_URL) + + spyOnFetch({ + responseBody: { message: "mocked internal server error" }, + status: 500, + }) + + await expect( + client.getResourceByPath("/server-error") + ).rejects.toThrow("500 mocked internal server error") + }) + test("throws an error for invalid params", async () => { const client = new DrupalClient(BASE_URL) @@ -836,6 +849,19 @@ describe("translatePath()", () => { expect(path).toBeNull() }) + test("throws an error for server errors", async () => { + const client = new DrupalClient(BASE_URL) + + spyOnFetch({ + responseBody: { message: "mocked internal server error" }, + status: 500, + }) + + await expect(client.translatePath("/server-error")).rejects.toThrowError( + "500 mocked internal server error" + ) + }) + test("makes un-authenticated requests by default", async () => { const client = new DrupalClient(BASE_URL) const fetchSpy = jest.spyOn(client, "fetch")