Skip to content

quic: add proper error codes & messages for QUIC failures#63198

Merged
nodejs-github-bot merged 7 commits into
nodejs:mainfrom
pimterry:fix-quic-error-codes
May 28, 2026
Merged

quic: add proper error codes & messages for QUIC failures#63198
nodejs-github-bot merged 7 commits into
nodejs:mainfrom
pimterry:fix-quic-error-codes

Conversation

@pimterry
Copy link
Copy Markdown
Member

@pimterry pimterry commented May 8, 2026

This wraps QUIC errors, providing useful error codes and messages for the defined error code cases from both OpenSSL and ngtcp2.

Before this, QUIC errors looked like:

// Application error with an explicit reason string:
Error [ERR_QUIC_APPLICATION_ERROR]: A QUIC application error occurred. 42n [client shutdown]
    at [kFinishClose] (node:internal/quic/quic:3505:22)
    at Session.onSessionClose (node:internal/quic/quic:679:31) {
  code: 'ERR_QUIC_APPLICATION_ERROR'
}

// All our internal errors:
Error [ERR_QUIC_TRANSPORT_ERROR]: A QUIC transport error occurred. 296n [undefined]
    at [kFinishClose] (node:internal/quic/quic:3502:22)
    at Session.onSessionClose (node:internal/quic/quic:679:31) {
  code: 'ERR_QUIC_TRANSPORT_ERROR'
}

Now they look like:

Error [ERR_QUIC_APPLICATION_ERROR]: QUIC application error 42: client shutdown
    at makeQuicError (node:internal/quic/quic:999:15)
    at [kFinishClose] (node:internal/quic/quic:3552:22)
    at Session.onSessionClose (node:internal/quic/quic:681:31) {
  code: 'ERR_QUIC_APPLICATION_ERROR',
  errorCode: 42n,
  type: 'application',
  reason: 'client shutdown'
}

Error [ERR_QUIC_TRANSPORT_ERROR]: QUIC transport error handshake failure (296)
    at makeQuicError (node:internal/quic/quic:988:15)
    at [kFinishClose] (node:internal/quic/quic:3534:22)
    at Session.onSessionClose (node:internal/quic/quic:681:31) {
  code: 'ERR_QUIC_TRANSPORT_ERROR',
  errorCode: 296n,
  type: 'transport',
  errorName: 'handshake failure'
}

@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/quic

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. labels May 8, 2026
@pimterry pimterry force-pushed the fix-quic-error-codes branch from 31b4709 to aefee4f Compare May 8, 2026 13:41
Comment thread lib/internal/quic/quic.js Outdated
Comment thread src/quic/data.cc
@codecov
Copy link
Copy Markdown

codecov Bot commented May 8, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.29%. Comparing base (8257091) to head (c5bd305).
⚠️ Report is 14 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #63198      +/-   ##
==========================================
- Coverage   90.32%   90.29%   -0.03%     
==========================================
  Files         730      730              
  Lines      234671   234825     +154     
  Branches    43946    43956      +10     
==========================================
+ Hits       211965   212043      +78     
- Misses      14423    14492      +69     
- Partials     8283     8290       +7     
Files with missing lines Coverage Δ
lib/internal/errors.js 97.65% <ø> (-0.01%) ⬇️
lib/internal/quic/quic.js 100.00% <100.00%> (ø)

... and 30 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@trivikr trivikr added the quic Issues and PRs related to the QUIC implementation / HTTP/3. label May 11, 2026
@pimterry pimterry added the commit-queue-squash Add this label to instruct the Commit Queue to squash all the PR commits into the first one. label May 11, 2026
@pimterry pimterry requested a review from jasnell May 11, 2026 13:45
Comment thread lib/internal/errors.js
Comment thread src/quic/data.cc Outdated
Comment thread src/quic/session.cc Outdated
Copy link
Copy Markdown
Contributor

@Ethan-Arrowood Ethan-Arrowood left a comment

Choose a reason for hiding this comment

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

this is a great change.

Copy link
Copy Markdown
Contributor

@Ethan-Arrowood Ethan-Arrowood left a comment

Choose a reason for hiding this comment

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

this is a great change.

@pimterry pimterry force-pushed the fix-quic-error-codes branch from 40eebfd to 60b6e3b Compare May 18, 2026 16:16
@pimterry
Copy link
Copy Markdown
Member Author

Updated to use bindingdata, rebased and force pushed because we need to update the test from #63193 (just merged) as well since that asserted on the error message.

Copy link
Copy Markdown
Member

@metcoder95 metcoder95 left a comment

Choose a reason for hiding this comment

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

lgtm

Copy link
Copy Markdown
Member

@Qard Qard left a comment

Choose a reason for hiding this comment

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

Is there some reason you're undid the use of the existing core errors system? Shouldn't we be keeping that?

Comment thread lib/internal/quic/quic.js
Comment on lines +985 to +992
function makeQuicError(code, prefix, type, errorCode, reason, errorName) {
const err = new QuicError(
quicErrorMessage(prefix, errorCode, reason, errorName),
{ errorCode, code, type });
if (reason) err.reason = reason;
if (errorName) err.errorName = errorName;
return err;
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should we not keep the same error construction mechanism as the others? We lose a bunch of things by not using that. Not sure we should be taking these out of the global errors set.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This was a suggestion here, changed here.

We still use standard error codes, but we use a single QuicError class instead of the standard construction of per-code error classes: https://github.com/nodejs/node/blob/main/doc/api/quic.md#class-quicerror. This error class is used by users as well to control QUIC error behaviour, and this approach gives us consistent errors for every kind of failure at the protocol level. I don't feel strongly about it myself, but it seemed like a reasonable suggestion and having a single QUIC error class is tidy.

What do we lose by not using the standard error mechanism vs this setup?

Copy link
Copy Markdown
Member

@Qard Qard May 22, 2026

Choose a reason for hiding this comment

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

We lose the hideStackFrames logic, which means we'll see a bunch more internals things in stack traces here which we might not want to surface, like every validator gains a stack line without this. I'm not against this change, but just want to be sure that special-casing this is acceptable.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

In this case, I think the previous code didn't do this either - our validators do hide internal stack traces, but AFAICT the normal error code definitions don't do this unless you use HideStackFramesError explicitly.

It is easy to do though, and I agree it'd be a nice improvement - I've just pushed a commit that adds ErrorCaptureStackTrace(err, makeQuicError) here, which will omit these internal bits from the stack in the same way. This mirrors the equivalent setup for custom errors elsewhere like

function handleErrorFromBinding(ctx) {
if (ctx.errno !== undefined) { // libuv error numbers
const err = new UVException(ctx);
ErrorCaptureStackTrace(err, handleErrorFromBinding);
throw err;
}
if (ctx.error !== undefined) { // Errors created in C++ land.
// TODO(joyeecheung): currently, ctx.error are encoding errors
// usually caused by memory problems. We need to figure out proper error
// code(s) for this.
ErrorCaptureStackTrace(ctx.error, handleErrorFromBinding);
throw ctx.error;
}
}
for FS bindings.

Is that what you were looking for?

Copy link
Copy Markdown
Member

@Qard Qard left a comment

Choose a reason for hiding this comment

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

Linter seems to be complaining, but otherwise LGTM.

Move error paths added on main onto the new QuicError flow here, and fix
the error code in CheckStreamIdleTimeout, which was incorrect and so
failed validation.
@pimterry pimterry force-pushed the fix-quic-error-codes branch from 6adb825 to c5bd305 Compare May 28, 2026 09:57
@pimterry
Copy link
Copy Markdown
Member Author

Linter seems to be complaining, but otherwise LGTM.

Yeah, linting passed in isolation but failed on the merge commit due to new errors added elsewhere.

I've now rebased, fixed the conflicting changes so everything'll hopefully pass, and force pushed. If you have a second to re-review @Qard I'd appreciate it! 🙏 Thanks

@pimterry pimterry added the request-ci Add this label to start a Jenkins CI on a PR. label May 28, 2026
@github-actions github-actions Bot removed the request-ci Add this label to start a Jenkins CI on a PR. label May 28, 2026
@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

@pimterry pimterry added the commit-queue Add this label to land a pull request using GitHub Actions. label May 28, 2026
@nodejs-github-bot nodejs-github-bot removed the commit-queue Add this label to land a pull request using GitHub Actions. label May 28, 2026
@nodejs-github-bot nodejs-github-bot merged commit e1ae3a5 into nodejs:main May 28, 2026
73 checks passed
@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

Landed in e1ae3a5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c++ Issues and PRs that require attention from people who are familiar with C++. commit-queue-squash Add this label to instruct the Commit Queue to squash all the PR commits into the first one. lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. quic Issues and PRs related to the QUIC implementation / HTTP/3.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants