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

rework error return values #3159

Merged
merged 8 commits into from
May 1, 2021
Merged

rework error return values #3159

merged 8 commits into from
May 1, 2021

Conversation

marten-seemann
Copy link
Member

Fixes #2441.

This is a massive refactor changing the way we return QUIC errors. Calls to the session (and to streams) can now different errors, which can be checked with errors.Is / errors.As:

  • quic.TransportError: for errors triggered by the QUIC transport (in many cases a misbehaving peer)
  • quic.ApplicationError: for errors triggered by the application running on top of QUIC
  • quic.IdleTimeoutError: when the peer goes away unexpectedly (this is a net.Error timeout error)
  • quic.HandshakeTimeoutError: when the cryptographic handshake takes too long (this is a net.Error timeout error)
  • quic.StatelessResetError: when we receive a stateless reset (this is a net.Error temporary error)
  • quic.VersionNegotiationError: returned by the client, when there's no version overlap between the peers

In addition to that, streams that are canceled return a:

  • quic.StreamError: both for local and remote cancellations

@mvdan, what do you think about this? Do the API changes here make sense to you?

@codecov
Copy link

codecov bot commented Apr 26, 2021

Codecov Report

Merging #3159 (3af0597) into master (ddeb228) will increase coverage by 0.00%.
The diff coverage is 92.80%.

Impacted file tree graph

@@           Coverage Diff           @@
##           master    #3159   +/-   ##
=======================================
  Coverage   85.43%   85.43%           
=======================================
  Files         131      132    +1     
  Lines        9747     9824   +77     
=======================================
+ Hits         8327     8393   +66     
- Misses       1048     1058   +10     
- Partials      372      373    +1     
Impacted Files Coverage Δ
http3/error_codes.go 100.00% <ø> (ø)
internal/handshake/crypto_setup.go 65.71% <0.00%> (-0.47%) ⬇️
internal/protocol/protocol.go 100.00% <ø> (ø)
stream.go 86.49% <ø> (-0.69%) ⬇️
streams_map_incoming_generic.go 92.22% <50.00%> (ø)
errors.go 66.67% <66.67%> (ø)
http3/client.go 89.35% <83.33%> (ø)
http3/server.go 68.38% <88.89%> (ø)
session.go 77.83% <90.32%> (+0.21%) ⬆️
client.go 79.37% <100.00%> (ø)
... and 27 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ddeb228...3af0597. Read the comment docs.

@marten-seemann marten-seemann force-pushed the error-returns branch 5 times, most recently from 129306f to 5578482 Compare April 26, 2021 13:00
)

type (
TransportError = qerr.TransportError
Copy link
Member Author

Choose a reason for hiding this comment

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

Now this is a bit weird. We have a

  1. TransportError: the type of a transport error
  2. TransportErrorCode: the type of the error code for transport errors (a uint64)
  3. TransportErrorErrorCode: the error code the the TRANSPORT_ERROR (see 0xa in https://www.ietf.org/archive/id/draft-ietf-quic-transport-34.html#name-transport-error-codes)

Copy link

@mvdan mvdan Apr 28, 2021

Choose a reason for hiding this comment

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

TransportErrorCode

I guess just ErrorCode is not an option?

TransportErrorErrorCode: the error code the the TRANSPORT_ERROR (see 0xa in https://www.ietf.org/archive/id/draft-ietf-quic-transport-34.html#name-transport-error-codes)

not sure I follow; that page shows PROTOCOL_VIOLATION for 0xa. Could you not use ProtocolViolation?

Copy link
Member Author

Choose a reason for hiding this comment

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

Sorry, I meant 0xc.

Copy link

@mvdan mvdan Apr 28, 2021

Choose a reason for hiding this comment

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

Oh I see. Perhaps ErrorCodeApplication or TransportErrorCodeApplication? since the name seems to be APPLICATION_ERROR.


// A StatelessResetError occurs when we receive a stateless reset.
type StatelessResetError struct {
Token protocol.StatelessResetToken
Copy link
Member Author

Choose a reason for hiding this comment

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

It's nice to have all errors in the qerr package, but this means that we have to export the Token here. There's nothing wrong with that, but it's a piece of information that has no value to the user, so it would be nicer if it wasn't exported.

Copy link

Choose a reason for hiding this comment

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

since this is an internal package, does that matter?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, because we're exporting it in the quic package: type StatelessResetError = qerr.StatelessResetError

session.go Outdated
if !errors.Is(e, qerr.ErrIdleTimeout) && !errors.Is(e, qerr.ErrHandshakeTimeout) &&
!errors.Is(e, &StatelessResetError{}) && !errors.Is(e, &VersionNegotiationError{}) &&
!errors.Is(e, &errCloseForRecreating{}) &&
!errors.Is(e, &qerr.ApplicationError{}) && !errors.Is(e, &qerr.TransportError{}) {
Copy link
Member Author

Choose a reason for hiding this comment

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

🤢

Copy link

Choose a reason for hiding this comment

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

Hmm, can we not use a type switch here? I get that As is meant to peek at the error's layers, but I think Is isn't meant to do that - so just doing a type switch on the top-level error might be fine.

Copy link
Member Author

Choose a reason for hiding this comment

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

A type switch with 7 empty cases and one default case that has some logic? Maybe that's at least a little bit nicer?

Copy link

Choose a reason for hiding this comment

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

Indeed, I'd find that nicer. You can even group the cases, like:

switch e.(type) {
case T1, T2, T3...:
default:
    // your logic
}

Copy link
Member Author

Choose a reason for hiding this comment

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

I get that As is meant to peek at the error's layers, but I think Is isn't meant to do that

I think it is. From the docs:

Is reports whether any error in err's chain matches target.

Now we shouldn't encounter any wrapped errors here (at least not with the current code), but I guess it's still safer to use errors.Is.

@mvdan
Copy link

mvdan commented Apr 28, 2021

@mvdan, what do you think about this? Do the API changes here make sense to you?

From the PR description you wrote, it sounds fine.

Copy link
Member

@lucas-clemente lucas-clemente left a comment

Choose a reason for hiding this comment

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

Can you include your PR description as doc for the errors in the main package?

@marten-seemann marten-seemann merged commit b8f07c7 into master May 1, 2021
@marten-seemann marten-seemann deleted the error-returns branch May 1, 2021 03:04
@marten-seemann marten-seemann added this to the v0.21 milestone May 3, 2021
@aschmahmann aschmahmann mentioned this pull request May 14, 2021
71 tasks
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.

Extract the ErrorCode
3 participants