Skip to content

Conversation

rkistner
Copy link
Contributor

@rkistner rkistner commented Jul 2, 2025

In earlier versions, undici did not include the underlying cause of errors on websocket connection failures, instead just giving a generic Received network error or non-101 status code., making debugging difficult. This includes connection failures, TLS failures, proxy errors, etc. As a workaround, we used a custom Dispatcher to record the underlying errors.

In v7.11.0, this was fixed by adding the cause property. This PR now removes the custom Dispatcher and just relies on the upstream directly.

Note that this does change the error reported, and you have to use error.cause[.cause] to get to the underlying issue.

Sample error (502 on a proxy) with this change:

[PowerSyncStream] Error: Received network error or non-101 status code.
    at #onFail (/home/ralf/src/powersync-js/packages/node/node_modules/undici/lib/web/websocket/websocket.js:469:16)
    at Object.onFail (/home/ralf/src/powersync-js/packages/node/node_modules/undici/lib/web/websocket/websocket.js:63:50)
    at failWebsocketConnection (/home/ralf/src/powersync-js/packages/node/node_modules/undici/lib/web/websocket/connection.js:319:11)
    at Object.processResponse (/home/ralf/src/powersync-js/packages/node/node_modules/undici/lib/web/websocket/connection.js:108:9)
    at /home/ralf/src/powersync-js/packages/node/node_modules/undici/lib/web/fetch/index.js:1072:19
    at node:internal/process/task_queues:140:7
    at AsyncResource.runInAsyncScope (node:async_hooks:206:9)
    at AsyncResource.runMicrotask (node:internal/process/task_queues:137:8)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
  [cause]: DOMException [Error]: Request was cancelled.
      at new DOMException (node:internal/per_context/domexception:53:5)
      at makeAppropriateNetworkError (/home/ralf/src/powersync-js/packages/node/node_modules/undici/lib/web/fetch/response.js:484:38)
      at httpNetworkFetch (/home/ralf/src/powersync-js/packages/node/node_modules/undici/lib/web/fetch/index.js:1877:14)
      at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
      at async httpNetworkOrCacheFetch (/home/ralf/src/powersync-js/packages/node/node_modules/undici/lib/web/fetch/index.js:1562:29)
      at async httpFetch (/home/ralf/src/powersync-js/packages/node/node_modules/undici/lib/web/fetch/index.js:1133:33)
      at async mainFetch (/home/ralf/src/powersync-js/packages/node/node_modules/undici/lib/web/fetch/index.js:590:18) {
    cause: RequestAbortedError [AbortError]: Proxy response (502) !== 200 when HTTP Tunneling
        at Client.connect (/home/ralf/src/powersync-js/packages/node/node_modules/undici/lib/dispatcher/proxy-agent.js:154:22)
        at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
      code: 'UND_ERR_ABORTED'
    }
  }
}

Before, with ErrorRecordingDispatcher:

[PowerSyncStream] RequestAbortedError [AbortError]: Proxy response (502) !== 200 when HTTP Tunneling
    at Client.connect (/home/ralf/src/powersync-js/packages/node/node_modules/undici/lib/dispatcher/proxy-agent.js:153:22)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
  code: 'UND_ERR_ABORTED'

Before, without ErrorRecordingDispatcher:

[PowerSyncStream] Error: Received network error or non-101 status code.
    at #onFail (/home/ralf/src/powersync-js/packages/node/node_modules/undici/lib/web/websocket/websocket.js:469:16)
    at Object.onFail (/home/ralf/src/powersync-js/packages/node/node_modules/undici/lib/web/websocket/websocket.js:63:43)
    at failWebsocketConnection (/home/ralf/src/powersync-js/packages/node/node_modules/undici/lib/web/websocket/connection.js:318:11)
    at Object.processResponse (/home/ralf/src/powersync-js/packages/node/node_modules/undici/lib/web/websocket/connection.js:108:9)
    at /home/ralf/src/powersync-js/packages/node/node_modules/undici/lib/web/fetch/index.js:1072:19
    at node:internal/process/task_queues:140:7
    at AsyncResource.runInAsyncScope (node:async_hooks:206:9)
    at AsyncResource.runMicrotask (node:internal/process/task_queues:137:8)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

@rkistner rkistner requested a review from stevensJourney July 2, 2025 11:13
Copy link

changeset-bot bot commented Jul 2, 2025

🦋 Changeset detected

Latest commit: 335b04d

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@powersync/node Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link
Collaborator

@stevensJourney stevensJourney left a comment

Choose a reason for hiding this comment

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

Awesome!

@rkistner rkistner merged commit 31e942f into main Jul 2, 2025
9 checks passed
@rkistner rkistner deleted the undici-errors branch July 2, 2025 13:40
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.

2 participants