github.com/sagernet/quic-go@v0.43.1-beta.1/http3/error.go (about)

     1  package http3
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  
     7  	"github.com/sagernet/quic-go"
     8  )
     9  
    10  // Error is returned from the round tripper (for HTTP clients)
    11  // and inside the HTTP handler (for HTTP servers) if an HTTP/3 error occurs.
    12  // See section 8 of RFC 9114.
    13  type Error struct {
    14  	Remote       bool
    15  	ErrorCode    ErrCode
    16  	ErrorMessage string
    17  }
    18  
    19  var _ error = &Error{}
    20  
    21  func (e *Error) Error() string {
    22  	s := e.ErrorCode.string()
    23  	if s == "" {
    24  		s = fmt.Sprintf("H3 error (%#x)", uint64(e.ErrorCode))
    25  	}
    26  	// Usually errors are remote. Only make it explicit for local errors.
    27  	if !e.Remote {
    28  		s += " (local)"
    29  	}
    30  	if e.ErrorMessage != "" {
    31  		s += ": " + e.ErrorMessage
    32  	}
    33  	return s
    34  }
    35  
    36  func maybeReplaceError(err error) error {
    37  	if err == nil {
    38  		return nil
    39  	}
    40  
    41  	var (
    42  		e      Error
    43  		strErr *quic.StreamError
    44  		appErr *quic.ApplicationError
    45  	)
    46  	switch {
    47  	default:
    48  		return err
    49  	case errors.As(err, &strErr):
    50  		e.Remote = strErr.Remote
    51  		e.ErrorCode = ErrCode(strErr.ErrorCode)
    52  	case errors.As(err, &appErr):
    53  		e.Remote = appErr.Remote
    54  		e.ErrorCode = ErrCode(appErr.ErrorCode)
    55  		e.ErrorMessage = appErr.ErrorMessage
    56  	}
    57  	return &e
    58  }