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

TypeError: Network Request Failed #971

Open
Smankusors opened this issue Nov 7, 2021 · 4 comments
Open

TypeError: Network Request Failed #971

Smankusors opened this issue Nov 7, 2021 · 4 comments
Labels
bug good first issue help wanted

Comments

@Smankusors
Copy link

@Smankusors Smankusors commented Nov 7, 2021

Describe the bug

I received this error whenever there's code error on the handler code.

Environment

This unit testing running on Node environment

  • msw: 0.35.0
  • nodejs: 16.6.0
  • npm: 7.24.1

To Reproduce

Take a look at the example of the handler code below:

import { rest } from 'msw'

export const handlers = [
  rest.post('/login', (req, res, ctx) => {
    const { username } = req.body
    i = 1 / 0
    return res(
      ctx.json({
        id: 'f79e82e8-c34a-4dc7-a49e-9fadc0979fda',
        username,
        firstName: 'John',
        lastName: 'Maverick',
      })
    )
  }),
]

Expected behavior

The error should appear like this when testing

    ReferenceError: i is not defined
        at resolver ([project path]\src\mocks\handlers.js:6:6)
        at [rest of stack traces]

Current behavior

But instead, TypeError appears

    TypeError: Network request failed

      at node_modules/whatwg-fetch/dist/fetch.umd.js:535:18
      at Timeout.task [as _onTimeout] (node_modules/jsdom/lib/jsdom/browser/Window.js:516:19)

It seems like when the handler code failed, there's no response being sent back, resulting what it looks like timeout.

More info

I'm able to make the error shows up in the console by editing this line

const result = this.resolverGenerator || (await resolver(req, res, ctx))

into this

      try {
        result = this.resolverGenerator || (await resolver(req, res, ctx))
      } catch (error) {
        console.error(error)
        return null
      }

but it's kinda ugly? What's best approach for this?

@kettanaito
Copy link
Member

@kettanaito kettanaito commented Nov 8, 2021

Hey, @Smankusors.

The current behavior is correct. MSW stands for a mocked server-side code you're writing. If there'd be such a code as 1 / 0 on the server, you wouldn't get the direct exception for it (normally). Instead, your request would fail, receive a 500 response status code, with some additional information (if such was implemented by the server).

That's exactly how MSW behaves:

  1. Your request receives a 500 response (Network request failed). Note that this behavior is controlled by the request client and window.fetch may produce one exception while something like axios—another.
  2. The actual 500 response contains the original exception you're expecting in its body. Locate that failed request in the "Network" tab, click on it, choose to "Preview" its body. You will see a JSON body with the error and its location.

That being said, if this behavior is confusing to developers, I see little harm in duplicating the error message directly to the console for better visibility. But I'd still leave the behavior I described above intact.

@kettanaito
Copy link
Member

@kettanaito kettanaito commented Nov 8, 2021

If I'm not mistaken, such exception will bubble to this catch block in createRequestListener function:

} catch (error) {
if (error instanceof NetworkError) {
// Treat emulated network error differently,
// as it is an intended exception in a request handler.
return channel.send({
type: 'NETWORK_ERROR',
payload: {
name: error.name,
message: error.message,
},
})
}
// Treat all the other exceptions in a request handler
// as unintended, alerting that there is a problem needs fixing.
channel.send({
type: 'INTERNAL_ERROR',
payload: {
status: 500,
body: JSON.stringify({
errorType: error.constructor.name,
message: error.message,
location: error.stack,
}),
},
})
}
}

This is also how such exceptions are translated to 500 error responses (signaling NETWORK_ERROR or INTERNAL_ERROR events to the worker).

I believe if we add the suggested console.error(error) call at the beginning of this catch block we'll get the expected behavior.

@Smankusors, would you be interested in working on this? I will support you during the code review if you decide so.

@kettanaito kettanaito added good first issue help wanted labels Nov 8, 2021
@Smankusors
Copy link
Author

@Smankusors Smankusors commented Nov 8, 2021

yeah it should return 500 response, but it doesn't. The timeout returned instead.

I have tried console.log everywhere in the createRequestListener.ts, but not a single log is even appear on the console

Take a look of my modified createRequestListener

https://github.com/Smankusors/msw/blob/52ffe4117d89820c7c29152e860c4fa8ff15e2ee/src/utils/worker/createRequestListener.ts

@teamgroove
Copy link

@teamgroove teamgroove commented Apr 28, 2022

My jest-tests exit the process because of this, instead of just failing the test.
The fix doesn't have been merged / released yet, i think.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug good first issue help wanted
Development

No branches or pull requests

3 participants