Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 687: Throw error when backend error in /router/translate-path #688

Conversation

marcorcau
Copy link

@marcorcau marcorcau commented Feb 19, 2024

to avoid re-generation with 404.

This pull request is for: (mark with an "x")

  • examples/*
  • modules/next
  • packages/next-drupal
  • starters/basic-starter
  • starters/graphql-starter
  • Other

GitHub Issue: #687

  • I need help adding tests. (mark with an "x")

Describe your changes

When /router/translate-path?path=xxx response is "Internal server error" (starts with "5") throw Error instead of returning the same as if it was 404 Not Found to avoid re-generation with 404.

Copy link

vercel bot commented Feb 19, 2024

Someone is attempting to deploy a commit to the Chapter Three Team on Vercel.

A member of the Team first needs to authorize it.

@marcorcau marcorcau marked this pull request as draft February 19, 2024 22:31
…is 50x

Until now it was always treated as 404 path not found. This treats different 404 than 50x.

BREAKING CHANGE:
Might break sites relying on response being the same in 404 than in 50x.

Fixes chapter-three#687
@marcorcau marcorcau marked this pull request as ready for review February 20, 2024 09:40
@@ -910,6 +910,10 @@ export class DrupalClient {
withAuth: options.withAuth,
})

if (response.status && response.status.toString().startsWith("5")) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move this code block inside the if (!response?.ok) { code block below. We don't need to check this if the response is ok.

No need for response.status && since response.status is going to be a number.

Actually, the only "acceptable" error here is 404 not found, right?

We should check

if (response.status === 404) {
 return null
}

And otherwise throw the error. Right?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done !! Makes more sense this way, thanks!

@@ -910,6 +910,10 @@ export class DrupalClient {
withAuth: options.withAuth,
})

if (response.status && response.status.toString().startsWith("5")) {
throw new Error(`Server error.`)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not throw an error that contains info about the server error?

Please add status code and the error message from the JSON body.

Something like:

let errorMessage
try {
  errorMessage = `${response.status} ${(await response.json())?.message}`
} catch (e) {
  errorMessage = `${response.status} ${response.statusText}`
}
throw new Error(errorMessage)

We need to wrap the response.json() in a try/catch block because a 5xx error may cause Drupal to not respond with JSON.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done !! Would this.throwError be preferable instead of throw?

await expect(
client.translatePath("/internal-server-error")
).rejects.toThrowError(`Server error.`)
})
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just refactored the Jest tests. And the translatePath() tests are now found in packages/next-drupal/tests/DrupalClient/fetch-related-methods.test.ts.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was actually resource-methods.test.ts, right?

Comment on lines 1485 to 1488
jest.spyOn(client, "fetch")
.mockImplementation(
jest.fn(() => Promise.reject(new Error(`Server error.`))) as jest.Mock
)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When fetch receives a 500 response, it doesn't throw an error; it simply returns the response with the error information. You've mocked fetch throwing an error (which can happen if you don't pass the right arguments, etc.); see https://developer.mozilla.org/en-US/docs/Web/API/fetch#exceptions

You need to mock a failing response. Fortunately, I just added a test helper function that makes these easy to do.

spyOnFetch({ responseBody: { message: "mocked internal server error" }, status: 500 })

Copy link
Author

@marcorcau marcorcau Apr 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yeah. Sorry. I'm not that familiar with it. Fixed.

But I was unable of adding test code for the catch part in translatePath. fetchMockImplementation ensures that is valid json response. Any suggestion or just leave it with the c8 ignore.

@marcorcau marcorcau marked this pull request as draft February 22, 2024 16:15
cruno91 and others added 23 commits March 26, 2024 18:16
… 7.0.2 (chapter-three#690)

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
BREAKING CHANGE:
The JsonApiWithAuthOptions type has been renamed to JsonApiWithAuthOption. The
JsonApiWithLocaleOptions type is now considered deprecated for DrupalClient
usage and can be replaced with the JsonApiOptions type.
…pter-three#697)

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
The `withAuth` option belongs to the DrupalClient.fetch() method but was
mistakenly being passed to the init param of the global fetch and custom fetcher
functions.
@JohnAlbin
Copy link
Collaborator

I just noticed that getResourceByPath() and its tests will also need to be updated for this bug.

Cleaner flow and throw error with relevant message in DrupalClient.translatePath().
Fix test did not reproduce actual response.

BREAKING CHANGE:
Might break sites relying on response being the same in 404 than in 50x.

Fixes chapter-three#687
…th()

Add differentiate between server error and 404 in getResourceByPath as it was done in translatePath.
Add a test for it.

BREAKING CHANGE:
Might break sites relying on response being the same in 404 than in 50x.

Fixes chapter-three#687
Add c8 ignore to catch branch. fetchMockImplementation forces the response to be valid json.
Could only be tested adding an extra argument to not return json but arbitrary response.

BREAKING CHANGE:
Might break sites relying on response being the same in 404 than in 50x.

Fixes chapter-three#687
@marcorcau
Copy link
Author

I just noticed that getResourceByPath() and its tests will also need to be updated for this bug.

I've added this to the MR and also a test for it, but now there is a bit of code duplication:

      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)

Should I refactor that in a common function or wejust accept it?

@marcorcau marcorcau marked this pull request as ready for review April 14, 2024 12:29
@JohnAlbin
Copy link
Collaborator

Looking at this more, I realize that the fix is a lot more complicated then "just update getResourceByPath()".

I've taken the code from the PR and added to it to make a new PR. #743

Thanks for reporting this bug and thanks for all your effort in fixing it, @marcorcau!

@JohnAlbin JohnAlbin closed this Apr 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.