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

XMLHttpRequest errors are not handled correctly #3425

Closed
liamaharon opened this issue Mar 22, 2020 · 22 comments · Fixed by #3947
Closed

XMLHttpRequest errors are not handled correctly #3425

liamaharon opened this issue Mar 22, 2020 · 22 comments · Fixed by #3947
Assignees
Labels
1.x 1.0 related issues Bug Addressing a bug In Progress Currently being worked on P2 Medium severity bugs

Comments

@liamaharon
Copy link

liamaharon commented Mar 22, 2020

In the event of an error occurring during a XMLHttpRequest, onreadystatechange is called when

  • request.readyState is 4
  • request.responseText is ""
  • request.status is 0

The following code that handles http requests does not handle this case, and can return a misleading error to the user when it occurs

https://github.com/ethereum/web3.js/blob/dee72e00883c5a23a47b6d3c1d27304ab1d4922e/packages/web3-providers-http/src/index.js#L87-L125

Let's pretend a machine has exhausted all of it's ephemeral ports right before web3.js tries to send a request. Here's what happens

  1. HttpProvider.prototype.send is called
  2. The request is crafted
  3. onreadystatechange and ontimeout handlers are assigned
  4. request.send is called with the payload
  5. The request fails before it is even sent to the destination due to there being no ephemeral ports available
  6. request.readyState is set to 4, request.responseText is set to "", request.status is set to 0 and the onreadystatechange handler is called
  7. web3.js tries to parse "" and throws an error that looks like this
  <rejected> Error: Invalid JSON RPC response: ""
      at Object.InvalidResponse (/home/liam/spells/web3.js/packages/web3-core-helpers/src/errors.js:42:16)
      at XMLHttpRequest.request.onreadystatechange (/home/liam/spells/web3.js/packages/web3-providers-http/src/index.js:108:32)
      at XMLHttpRequestEventTarget.dispatchEvent (/home/liam/spells/web3.js/packages/web3-providers-http/node_modules/xhr2-cookies/dist/xml-http-request-event-target.js:34:22)
      at XMLHttpRequest._setReadyState (/home/liam/spells/web3.js/packages/web3-providers-http/node_modules/xhr2-cookies/dist/xml-http-request.js:208:14)
      at XMLHttpRequest._onHttpRequestError (/home/liam/spells/web3.js/packages/web3-providers-http/node_modules/xhr2-cookies/dist/xml-http-request.js:349:14)
      at ClientRequest.<anonymous> (/home/liam/spells/web3.js/packages/web3-providers-http/node_modules/xhr2-cookies/dist/xml-http-request.js:252:61)
      at ClientRequest.emit (events.js:210:5)
      at ClientRequest.EventEmitter.emit (domain.js:475:20)
      at Socket.socketErrorListener (_http_client.js:406:9)
      at Socket.emit (events.js:210:5)
      at Socket.EventEmitter.emit (domain.js:475:20)
      at emitErrorNT (internal/streams/destroy.js:92:8)
      at emitErrorAndCloseNT (internal/streams/destroy.js:60:3)
      at processTicksAndRejections (internal/process/task_queues.js:80:21)

this error is misleading because it indicates that the node successfully received the request and actually returned an empty string in response, when in reality the request never even made it to the node and an empty string is just the default value set on request in an error scenario.

I believe this may be the cause of some other issues people have opened in the past like #3370 and #1919

I think it makes sense to at least add an onerror handler to the request, and in the case that a request fails the error thrown indicates that instead of a misleading InvalidResponse error.

I'm working on a PR for this.

@cgewecke cgewecke added the 1.x 1.0 related issues label Mar 23, 2020
@cgewecke
Copy link
Collaborator

@liamaharon Thanks for such a great description and analysis of this problem.

@wbt
Copy link
Contributor

wbt commented Apr 27, 2020

As an FYI: With the error lacking any particular code to check on, we and probably others are checking for a string match and when the error message changes to something more informative, that change will probably break our ability to handle it robustly (mainly by waiting a bit and trying again). We will need to coordinate code changes around the time of upgrade to adjust for that breaking change. Therefore, I would definitely recommend against rolling out a fix for this on e.g. the patch version number.

@github-actions
Copy link

github-actions bot commented Jul 3, 2020

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment, otherwise this issue will be closed in 7 days

@github-actions github-actions bot added the Stale Has not received enough activity label Jul 3, 2020
@wbt
Copy link
Contributor

wbt commented Jul 3, 2020

I don't think this should be marked as stale.

@cgewecke cgewecke removed the Stale Has not received enough activity label Jul 3, 2020
@github-actions
Copy link

github-actions bot commented Aug 3, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions. If you believe this was a mistake, please comment.

@github-actions github-actions bot added the Stale Has not received enough activity label Aug 3, 2020
@wbt
Copy link
Contributor

wbt commented Aug 3, 2020

I still don't think this should be marked as stale.

@github-actions github-actions bot removed the Stale Has not received enough activity label Aug 4, 2020
mergify bot pushed a commit to celo-org/celo-monorepo that referenced this issue Aug 11, 2020
### Description

- This change should fix the flakey `error: Invalid JSON RPC response: ""` error that we often see in the protocol test beforeEach hooks (particularly those for the Attestations contract). 

- Implements a custom beforeEachWithRetries hook for the protocol tests package that will optionally retry beforeEach hooks and add sleep in between retries. This is necessary to avoid flakiness that seems to be caused by port exhaustion in CI and a mishandling of the error by web3. (See web3/web3.js#3425 and web3/web3.js#926).

- I've only added `beforeEachWithRetries` to the Attestations tests because this error appears there the most. We can add it elsewhere in the future as needed.

### Other changes

None

### Tested

To see that this works, search logs for "retry" in https://circleci.com/gh/celo-org/celo-monorepo/248635

### Related issues

- Fixes #4570

### Backwards compatibility

Not applicable
@uluhonolulu
Copy link

I wish I could do something to help with this, I keep seeing this error and have to write dirty workaround code to handle it every time.

ewilz pushed a commit to ewilz/celo-monorepo that referenced this issue Sep 29, 2020
### Description

- This change should fix the flakey `error: Invalid JSON RPC response: ""` error that we often see in the protocol test beforeEach hooks (particularly those for the Attestations contract). 

- Implements a custom beforeEachWithRetries hook for the protocol tests package that will optionally retry beforeEach hooks and add sleep in between retries. This is necessary to avoid flakiness that seems to be caused by port exhaustion in CI and a mishandling of the error by web3. (See web3/web3.js#3425 and web3/web3.js#926).

- I've only added `beforeEachWithRetries` to the Attestations tests because this error appears there the most. We can add it elsewhere in the future as needed.

### Other changes

None

### Tested

To see that this works, search logs for "retry" in https://circleci.com/gh/celo-org/celo-monorepo/248635

### Related issues

- Fixes celo-org#4570

### Backwards compatibility

Not applicable
@github-actions
Copy link

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions. If you believe this was a mistake, please comment.

@github-actions github-actions bot added the Stale Has not received enough activity label Nov 26, 2020
@liamaharon
Copy link
Author

@uluhonolulu I have a PR in progress that addresses this, TODO is to get error codes thrown instead of strings. I don't have time to get around to finishing it right now, if you're still willing & able to help would be great if you could assist finishing it off #3426

@github-actions github-actions bot removed the Stale Has not received enough activity label Nov 27, 2020
@uluhonolulu
Copy link

@liamaharon I'll be happy to work on it. Do you think I'll be able to continue working on your PR (permissions?) or create a new one? (Sorry if it's a dumb question)

@github-actions
Copy link

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions. If you believe this was a mistake, please comment.

@github-actions github-actions bot added the Stale Has not received enough activity label Jan 27, 2021
@wbt
Copy link
Contributor

wbt commented Jan 27, 2021

@liamaharon Did you wind up being able to make any progress? It looks like you got an answer to that question on the PR!

@spacesailor24 spacesailor24 added the P2 Medium severity bugs label Mar 5, 2021
@uluhonolulu
Copy link

@spacesailor24 I promised to work on it, and I was planning to get it done over the weekend.

uluhonolulu added a commit to uluhonolulu/web3.js that referenced this issue Mar 10, 2021
uluhonolulu added a commit to uluhonolulu/web3.js that referenced this issue Mar 11, 2021
@koraykoska koraykoska added this to the Maintenance milestone Mar 24, 2021
@koraykoska koraykoska self-assigned this Mar 24, 2021
koraykoska pushed a commit that referenced this issue Apr 5, 2021
Added the custom error
@koraykoska koraykoska mentioned this issue Apr 5, 2021
16 tasks
@illuzen
Copy link

illuzen commented Apr 22, 2021

The workaround here is to use WebsocketProvider, at least in the case of truffle tests

@Polycarpik Polycarpik removed this from the Maintenance milestone May 12, 2021
@github-actions
Copy link

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions. If you believe this was a mistake, please comment.

@github-actions github-actions bot added the Stale Has not received enough activity label Jul 12, 2021
@wbt
Copy link
Contributor

wbt commented Jul 13, 2021

Is the fix for this still in progress?

@uluhonolulu
Copy link

@wbt I've created a pull request (#3947), but it didn't pass all tests (the same tests were failing before my changes), but then I stopped receiving notifications and missed the discussion there.

Not sure what is the story with the @koraykoska's fix.

@github-actions github-actions bot removed the Stale Has not received enough activity label Jul 14, 2021
uluhonolulu added a commit to uluhonolulu/web3.js that referenced this issue Sep 5, 2021
uluhonolulu added a commit to uluhonolulu/web3.js that referenced this issue Sep 5, 2021
spacesailor24 pushed a commit that referenced this issue Sep 8, 2021
* Improve http request error handling

* Update changelog.md

* Update mock response

* Add error code to HTTP connection error

* Propagate the original request error (#3425)

* Fixed a test (#3425)

Co-authored-by: Liam Aharon <[email protected]>
@github-actions
Copy link

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions. If you believe this was a mistake, please comment.

@github-actions github-actions bot added the Stale Has not received enough activity label Sep 12, 2021
@spacesailor24 spacesailor24 added In Progress Currently being worked on and removed Stale Has not received enough activity labels Sep 15, 2021
@jdevcs jdevcs linked a pull request Sep 16, 2021 that will close this issue
@jdevcs jdevcs mentioned this issue Oct 20, 2021
14 tasks
@philknows
Copy link

Will be addressed in 4.x http provider.

@jdevcs jdevcs closed this as completed Nov 25, 2021
@zon-dtravel
Copy link

I still got same error when use HttpProvider, any suggest?
this.web3 = new Web3(new Web3.providers.HttpProvider('provider'))

@ghost
Copy link

ghost commented Jul 5, 2022

Note that this issue has been addressed by the recent PR #5179 to replace the broken xhr2-cookies for the modern fetch API.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
1.x 1.0 related issues Bug Addressing a bug In Progress Currently being worked on P2 Medium severity bugs
Projects
None yet