github.com/MerlinKodo/quic-go@v0.39.2/internal/qerr/errors.go (about) 1 package qerr 2 3 import ( 4 "fmt" 5 "net" 6 7 "github.com/MerlinKodo/quic-go/internal/protocol" 8 ) 9 10 var ( 11 ErrHandshakeTimeout = &HandshakeTimeoutError{} 12 ErrIdleTimeout = &IdleTimeoutError{} 13 ) 14 15 type TransportError struct { 16 Remote bool 17 FrameType uint64 18 ErrorCode TransportErrorCode 19 ErrorMessage string 20 error error // only set for local errors, sometimes 21 } 22 23 var _ error = &TransportError{} 24 25 // NewLocalCryptoError create a new TransportError instance for a crypto error 26 func NewLocalCryptoError(tlsAlert uint8, err error) *TransportError { 27 return &TransportError{ 28 ErrorCode: 0x100 + TransportErrorCode(tlsAlert), 29 error: err, 30 } 31 } 32 33 func (e *TransportError) Error() string { 34 str := fmt.Sprintf("%s (%s)", e.ErrorCode.String(), getRole(e.Remote)) 35 if e.FrameType != 0 { 36 str += fmt.Sprintf(" (frame type: %#x)", e.FrameType) 37 } 38 msg := e.ErrorMessage 39 if len(msg) == 0 && e.error != nil { 40 msg = e.error.Error() 41 } 42 if len(msg) == 0 { 43 msg = e.ErrorCode.Message() 44 } 45 if len(msg) == 0 { 46 return str 47 } 48 return str + ": " + msg 49 } 50 51 func (e *TransportError) Is(target error) bool { 52 return target == net.ErrClosed 53 } 54 55 func (e *TransportError) Unwrap() error { 56 return e.error 57 } 58 59 // An ApplicationErrorCode is an application-defined error code. 60 type ApplicationErrorCode uint64 61 62 func (e *ApplicationError) Is(target error) bool { 63 return target == net.ErrClosed 64 } 65 66 // A StreamErrorCode is an error code used to cancel streams. 67 type StreamErrorCode uint64 68 69 type ApplicationError struct { 70 Remote bool 71 ErrorCode ApplicationErrorCode 72 ErrorMessage string 73 } 74 75 var _ error = &ApplicationError{} 76 77 func (e *ApplicationError) Error() string { 78 if len(e.ErrorMessage) == 0 { 79 return fmt.Sprintf("Application error %#x (%s)", e.ErrorCode, getRole(e.Remote)) 80 } 81 return fmt.Sprintf("Application error %#x (%s): %s", e.ErrorCode, getRole(e.Remote), e.ErrorMessage) 82 } 83 84 type IdleTimeoutError struct{} 85 86 var _ error = &IdleTimeoutError{} 87 88 func (e *IdleTimeoutError) Timeout() bool { return true } 89 func (e *IdleTimeoutError) Temporary() bool { return false } 90 func (e *IdleTimeoutError) Error() string { return "timeout: no recent network activity" } 91 func (e *IdleTimeoutError) Is(target error) bool { return target == net.ErrClosed } 92 93 type HandshakeTimeoutError struct{} 94 95 var _ error = &HandshakeTimeoutError{} 96 97 func (e *HandshakeTimeoutError) Timeout() bool { return true } 98 func (e *HandshakeTimeoutError) Temporary() bool { return false } 99 func (e *HandshakeTimeoutError) Error() string { return "timeout: handshake did not complete in time" } 100 func (e *HandshakeTimeoutError) Is(target error) bool { return target == net.ErrClosed } 101 102 // A VersionNegotiationError occurs when the client and the server can't agree on a QUIC version. 103 type VersionNegotiationError struct { 104 Ours []protocol.VersionNumber 105 Theirs []protocol.VersionNumber 106 } 107 108 func (e *VersionNegotiationError) Error() string { 109 return fmt.Sprintf("no compatible QUIC version found (we support %s, server offered %s)", e.Ours, e.Theirs) 110 } 111 112 func (e *VersionNegotiationError) Is(target error) bool { 113 return target == net.ErrClosed 114 } 115 116 // A StatelessResetError occurs when we receive a stateless reset. 117 type StatelessResetError struct { 118 Token protocol.StatelessResetToken 119 } 120 121 var _ net.Error = &StatelessResetError{} 122 123 func (e *StatelessResetError) Error() string { 124 return fmt.Sprintf("received a stateless reset with token %x", e.Token) 125 } 126 127 func (e *StatelessResetError) Is(target error) bool { 128 return target == net.ErrClosed 129 } 130 131 func (e *StatelessResetError) Timeout() bool { return false } 132 func (e *StatelessResetError) Temporary() bool { return true } 133 134 func getRole(remote bool) string { 135 if remote { 136 return "remote" 137 } 138 return "local" 139 }