diff --git a/internal/qerr/quic_error.go b/internal/qerr/errors.go similarity index 81% rename from internal/qerr/quic_error.go rename to internal/qerr/errors.go index d9c19a6fe..65d3e0071 100644 --- a/internal/qerr/quic_error.go +++ b/internal/qerr/errors.go @@ -29,11 +29,6 @@ func NewCryptoError(tlsAlert uint8, errorMessage string) *TransportError { } } -func (e *TransportError) Is(target error) bool { - _, ok := target.(*TransportError) - return ok -} - func (e *TransportError) Error() string { str := e.ErrorCode.String() if e.FrameType != 0 { @@ -63,11 +58,6 @@ type ApplicationError struct { var _ error = &ApplicationError{} -func (e *ApplicationError) Is(target error) bool { - _, ok := target.(*ApplicationError) - return ok -} - func (e *ApplicationError) Error() string { if len(e.ErrorMessage) == 0 { return fmt.Sprintf("Application error %#x", e.ErrorCode) @@ -82,10 +72,6 @@ var _ error = &IdleTimeoutError{} func (e *IdleTimeoutError) Timeout() bool { return true } func (e *IdleTimeoutError) Temporary() bool { return false } func (e *IdleTimeoutError) Error() string { return "timeout: no recent network activity" } -func (e *IdleTimeoutError) Is(target error) bool { - _, ok := target.(*IdleTimeoutError) - return ok -} type HandshakeTimeoutError struct{} @@ -94,10 +80,6 @@ var _ error = &HandshakeTimeoutError{} func (e *HandshakeTimeoutError) Timeout() bool { return true } func (e *HandshakeTimeoutError) Temporary() bool { return false } func (e *HandshakeTimeoutError) Error() string { return "timeout: handshake did not complete in time" } -func (e *HandshakeTimeoutError) Is(target error) bool { - _, ok := target.(*HandshakeTimeoutError) - return ok -} // A VersionNegotiationError occurs when the client and the server can't agree on a QUIC version. type VersionNegotiationError struct { @@ -109,11 +91,6 @@ func (e *VersionNegotiationError) Error() string { return fmt.Sprintf("no compatible QUIC version found (we support %s, server offered %s)", e.Ours, e.Theirs) } -func (e *VersionNegotiationError) Is(target error) bool { - _, ok := target.(*VersionNegotiationError) - return ok -} - // A StatelessResetError occurs when we receive a stateless reset. type StatelessResetError struct { Token protocol.StatelessResetToken @@ -125,10 +102,5 @@ func (e *StatelessResetError) Error() string { return fmt.Sprintf("received a stateless reset with token %x", e.Token) } -func (e *StatelessResetError) Is(target error) bool { - _, ok := target.(*StatelessResetError) - return ok -} - func (e *StatelessResetError) Timeout() bool { return false } func (e *StatelessResetError) Temporary() bool { return true } diff --git a/internal/qerr/errors_go116.go b/internal/qerr/errors_go116.go new file mode 100644 index 000000000..173cd91de --- /dev/null +++ b/internal/qerr/errors_go116.go @@ -0,0 +1,55 @@ +// +build go1.16 + +package qerr + +import ( + "net" +) + +func (e *TransportError) Is(target error) bool { + _, ok := target.(*TransportError) + if ok { + return true + } + return target == net.ErrClosed +} + +func (e *ApplicationError) Is(target error) bool { + _, ok := target.(*ApplicationError) + if ok { + return true + } + return target == net.ErrClosed +} + +func (e *IdleTimeoutError) Is(target error) bool { + _, ok := target.(*IdleTimeoutError) + if ok { + return true + } + return target == net.ErrClosed +} + +func (e *HandshakeTimeoutError) Is(target error) bool { + _, ok := target.(*HandshakeTimeoutError) + if ok { + return true + } + return target == net.ErrClosed +} + +func (e *VersionNegotiationError) Is(target error) bool { + _, ok := target.(*VersionNegotiationError) + if ok { + return true + } + return target == net.ErrClosed +} + +func (e *StatelessResetError) Is(target error) bool { + _, ok := target.(*StatelessResetError) + if ok { + return true + } + return target == net.ErrClosed +} diff --git a/internal/qerr/errors_go116_test.go b/internal/qerr/errors_go116_test.go new file mode 100644 index 000000000..f0063aa22 --- /dev/null +++ b/internal/qerr/errors_go116_test.go @@ -0,0 +1,22 @@ +// +build go1.16 + +package qerr + +import ( + "errors" + "net" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +var _ = Describe("QUIC Errors", func() { + It("says that errors are net.ErrClosed errors", func() { + Expect(errors.Is(&TransportError{}, net.ErrClosed)).To(BeTrue()) + Expect(errors.Is(&ApplicationError{}, net.ErrClosed)).To(BeTrue()) + Expect(errors.Is(&IdleTimeoutError{}, net.ErrClosed)).To(BeTrue()) + Expect(errors.Is(&HandshakeTimeoutError{}, net.ErrClosed)).To(BeTrue()) + Expect(errors.Is(&StatelessResetError{}, net.ErrClosed)).To(BeTrue()) + Expect(errors.Is(&VersionNegotiationError{}, net.ErrClosed)).To(BeTrue()) + }) +}) diff --git a/internal/qerr/errors_not_go116.go b/internal/qerr/errors_not_go116.go new file mode 100644 index 000000000..747022b7f --- /dev/null +++ b/internal/qerr/errors_not_go116.go @@ -0,0 +1,33 @@ +// +build !go1.16 + +package qerr + +func (e *TransportError) Is(target error) bool { + _, ok := target.(*TransportError) + return ok +} + +func (e *ApplicationError) Is(target error) bool { + _, ok := target.(*ApplicationError) + return ok +} + +func (e *IdleTimeoutError) Is(target error) bool { + _, ok := target.(*IdleTimeoutError) + return ok +} + +func (e *HandshakeTimeoutError) Is(target error) bool { + _, ok := target.(*HandshakeTimeoutError) + return ok +} + +func (e *VersionNegotiationError) Is(target error) bool { + _, ok := target.(*VersionNegotiationError) + return ok +} + +func (e *StatelessResetError) Is(target error) bool { + _, ok := target.(*StatelessResetError) + return ok +} diff --git a/internal/qerr/quic_error_test.go b/internal/qerr/errors_test.go similarity index 100% rename from internal/qerr/quic_error_test.go rename to internal/qerr/errors_test.go