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

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]: AQUICapplicationerroroccurred.42n[clientshutdown]at[kFinishClose](node:internal/quic/quic:3505:22)atSession.onSessionClose(node:internal/quic/quic:679:31){code: 'ERR_QUIC_APPLICATION_ERROR'}// All our internal errors:Error[ERR_QUIC_TRANSPORT_ERROR]: AQUICtransporterroroccurred.296n[undefined]at[kFinishClose](node:internal/quic/quic:3502:22)atSession.onSessionClose(node:internal/quic/quic:679:31){code: 'ERR_QUIC_TRANSPORT_ERROR'}

Now they look like:

Error[ERR_QUIC_APPLICATION_ERROR]: QUICapplicationerror42: clientshutdownatmakeQuicError(node:internal/quic/quic:999:15)at[kFinishClose](node:internal/quic/quic:3552:22)atSession.onSessionClose(node:internal/quic/quic:681:31){code: 'ERR_QUIC_APPLICATION_ERROR',errorCode: 42n,type: 'application',reason: 'client shutdown'}Error[ERR_QUIC_TRANSPORT_ERROR]: QUICtransporterrorhandshakefailure(296)atmakeQuicError(node:internal/quic/quic:988:15)at[kFinishClose](node:internal/quic/quic:3534:22)atSession.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-botnodejs-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
pimterryforce-pushed the fix-quic-error-codes branch from 31b4709 to aefee4fCompareMay 8, 2026 13:41
Comment threadlib/internal/quic/quic.js Outdated
Comment threadsrc/quic/data.cc
@codecov

codecovBot commented May 8, 2026

Copy link
Copy Markdown

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 linesCoverage Δ
lib/internal/errors.js97.65% <ø> (-0.01%)⬇️
lib/internal/quic/quic.js100.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.

@trivikrtrivikr added the quic Issues and PRs related to the QUIC implementation / HTTP/3. label May 11, 2026
@pimterrypimterry 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 jasnellMay 11, 2026 13:45
Comment threadlib/internal/errors.js
Comment threadsrc/quic/data.cc Outdated
Comment threadsrc/quic/session.cc Outdated

@Ethan-ArrowoodEthan-Arrowood left a comment

Copy link
Copy Markdown
Contributor

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.

@Ethan-ArrowoodEthan-Arrowood left a comment

Copy link
Copy Markdown
Contributor

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
pimterryforce-pushed the fix-quic-error-codes branch from 40eebfd to 60b6e3bCompareMay 18, 2026 16:16
@pimterry

Copy link
Copy Markdown
MemberAuthor

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.

@metcoder95metcoder95 left a comment

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.

lgtm

@QardQard left a comment

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.

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

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
MemberAuthor

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?

@QardQardMay 22, 2026

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.

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
MemberAuthor

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

functionhandleErrorFromBinding(ctx){
if(ctx.errno!==undefined){// libuv error numbers
consterr=newUVException(ctx);
ErrorCaptureStackTrace(err,handleErrorFromBinding);
throwerr;
}
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);
throwctx.error;
}
}
for FS bindings.

Is that what you were looking for?

@QardQard left a comment

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.

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
pimterryforce-pushed the fix-quic-error-codes branch from 6adb825 to c5bd305CompareMay 28, 2026 09:57
@pimterry

Copy link
Copy Markdown
MemberAuthor

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

@pimterrypimterry added the request-ci Add this label to start a Jenkins CI on a PR. label May 28, 2026
@github-actionsgithub-actionsBot 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

@pimterrypimterry added the commit-queue Add this label to land a pull request using GitHub Actions. label May 28, 2026
@nodejs-github-botnodejs-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:mainMay 28, 2026
73 checks passed
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Landed in e1ae3a5

aduh95 pushed a commit that referenced this pull request May 30, 2026
Signed-off-by: Tim Perry <pimterry@gmail.com>
PR-URL: #63198
Reviewed-By: Ethan Arrowood <ethan@arrowood.dev>
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
aduh95 pushed a commit that referenced this pull request May 30, 2026
Signed-off-by: Tim Perry <pimterry@gmail.com>
PR-URL: #63198
Reviewed-By: Ethan Arrowood <ethan@arrowood.dev>
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
aduh95 pushed a commit to aduh95/node that referenced this pull request Jul 30, 2026
Signed-off-by: Tim Perry <pimterry@gmail.com>
PR-URL: nodejs#63198
Reviewed-By: Ethan Arrowood <ethan@arrowood.dev>
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
aduh95 pushed a commit to aduh95/node that referenced this pull request Aug 3, 2026
Signed-off-by: Tim Perry <pimterry@gmail.com>
PR-URL: nodejs#63198
Reviewed-By: Ethan Arrowood <ethan@arrowood.dev>
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
aduh95 pushed a commit that referenced this pull request Aug 6, 2026
Signed-off-by: Tim Perry <pimterry@gmail.com>
PR-URL: #63198
Backport-PR-URL: #64675
Reviewed-By: Ethan Arrowood <ethan@arrowood.dev>
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
Sign up for freeto 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-squashAdd this label to instruct the Commit Queue to squash all the PR commits into the first one.lib / srcIssues and PRs related to general changes in the lib or src directory.needs-ciPRs that need a full CI run.quicIssues and PRs related to the QUIC implementation / HTTP/3.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants

@pimterry@nodejs-github-bot@Qard@jasnell@metcoder95@Ethan-Arrowood@bjohansebas@trivikr