github.com/tumi8/quic-go@v0.37.4-tum/noninternal/qerr/errors_test.go (about)

     1  package qerr
     2  
     3  import (
     4  	"errors"
     5  	"net"
     6  
     7  	"github.com/tumi8/quic-go/noninternal/protocol"
     8  	. "github.com/onsi/ginkgo/v2"
     9  	. "github.com/onsi/gomega"
    10  )
    11  
    12  var _ = Describe("QUIC Errors", func() {
    13  	Context("Transport Errors", func() {
    14  		It("has a string representation", func() {
    15  			Expect((&TransportError{
    16  				ErrorCode:    FlowControlError,
    17  				ErrorMessage: "foobar",
    18  			}).Error()).To(Equal("FLOW_CONTROL_ERROR (local): foobar"))
    19  		})
    20  
    21  		It("has a string representation for empty error phrases", func() {
    22  			Expect((&TransportError{ErrorCode: FlowControlError}).Error()).To(Equal("FLOW_CONTROL_ERROR (local)"))
    23  		})
    24  
    25  		It("includes the frame type, for errors without a message", func() {
    26  			Expect((&TransportError{
    27  				Remote:    true,
    28  				ErrorCode: FlowControlError,
    29  				FrameType: 0x1337,
    30  			}).Error()).To(Equal("FLOW_CONTROL_ERROR (remote) (frame type: 0x1337)"))
    31  		})
    32  
    33  		It("includes the frame type, for errors with a message", func() {
    34  			Expect((&TransportError{
    35  				ErrorCode:    FlowControlError,
    36  				FrameType:    0x1337,
    37  				ErrorMessage: "foobar",
    38  			}).Error()).To(Equal("FLOW_CONTROL_ERROR (local) (frame type: 0x1337): foobar"))
    39  		})
    40  
    41  		Context("crypto errors", func() {
    42  			It("has a string representation for errors with a message", func() {
    43  				err := NewLocalCryptoError(0x42, "foobar")
    44  				Expect(err.Error()).To(Equal("CRYPTO_ERROR 0x142 (local): foobar"))
    45  			})
    46  
    47  			It("has a string representation for errors without a message", func() {
    48  				err := NewLocalCryptoError(0x2a, "")
    49  				Expect(err.Error()).To(Equal("CRYPTO_ERROR 0x12a (local): tls: bad certificate"))
    50  			})
    51  		})
    52  	})
    53  
    54  	Context("Application Errors", func() {
    55  		It("has a string representation for errors with a message", func() {
    56  			Expect((&ApplicationError{
    57  				ErrorCode:    0x42,
    58  				ErrorMessage: "foobar",
    59  			}).Error()).To(Equal("Application error 0x42 (local): foobar"))
    60  		})
    61  
    62  		It("has a string representation for errors without a message", func() {
    63  			Expect((&ApplicationError{
    64  				ErrorCode: 0x42,
    65  				Remote:    true,
    66  			}).Error()).To(Equal("Application error 0x42 (remote)"))
    67  		})
    68  	})
    69  
    70  	Context("timeout errors", func() {
    71  		It("handshake timeouts", func() {
    72  			//nolint:gosimple // we need to assign to an interface here
    73  			var err error
    74  			err = &HandshakeTimeoutError{}
    75  			nerr, ok := err.(net.Error)
    76  			Expect(ok).To(BeTrue())
    77  			Expect(nerr.Timeout()).To(BeTrue())
    78  			Expect(err.Error()).To(Equal("timeout: handshake did not complete in time"))
    79  		})
    80  
    81  		It("idle timeouts", func() {
    82  			//nolint:gosimple // we need to assign to an interface here
    83  			var err error
    84  			err = &IdleTimeoutError{}
    85  			nerr, ok := err.(net.Error)
    86  			Expect(ok).To(BeTrue())
    87  			Expect(nerr.Timeout()).To(BeTrue())
    88  			Expect(err.Error()).To(Equal("timeout: no recent network activity"))
    89  		})
    90  	})
    91  
    92  	Context("Version Negotiation errors", func() {
    93  		It("has a string representation", func() {
    94  			Expect((&VersionNegotiationError{
    95  				Ours:   []protocol.VersionNumber{2, 3},
    96  				Theirs: []protocol.VersionNumber{4, 5, 6},
    97  			}).Error()).To(Equal("no compatible QUIC version found (we support [0x2 0x3], server offered [0x4 0x5 0x6])"))
    98  		})
    99  	})
   100  
   101  	Context("Stateless Reset errors", func() {
   102  		token := protocol.StatelessResetToken{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf}
   103  
   104  		It("has a string representation", func() {
   105  			Expect((&StatelessResetError{Token: token}).Error()).To(Equal("received a stateless reset with token 000102030405060708090a0b0c0d0e0f"))
   106  		})
   107  
   108  		It("is a net.Error", func() {
   109  			//nolint:gosimple // we need to assign to an interface here
   110  			var err error
   111  			err = &StatelessResetError{}
   112  			nerr, ok := err.(net.Error)
   113  			Expect(ok).To(BeTrue())
   114  			Expect(nerr.Timeout()).To(BeFalse())
   115  		})
   116  	})
   117  
   118  	It("says that errors are net.ErrClosed errors", func() {
   119  		Expect(errors.Is(&TransportError{}, net.ErrClosed)).To(BeTrue())
   120  		Expect(errors.Is(&ApplicationError{}, net.ErrClosed)).To(BeTrue())
   121  		Expect(errors.Is(&IdleTimeoutError{}, net.ErrClosed)).To(BeTrue())
   122  		Expect(errors.Is(&HandshakeTimeoutError{}, net.ErrClosed)).To(BeTrue())
   123  		Expect(errors.Is(&StatelessResetError{}, net.ErrClosed)).To(BeTrue())
   124  		Expect(errors.Is(&VersionNegotiationError{}, net.ErrClosed)).To(BeTrue())
   125  	})
   126  })