gitee.com/sasukebo/go-micro/v4@v4.7.1/errors/errors.go (about)

     1  // Package errors provides a way to return detailed information
     2  // for an RPC request error. The error is normally JSON encoded.
     3  package errors
     4  
     5  import (
     6  	"encoding/json"
     7  	"errors"
     8  	"fmt"
     9  	"net/http"
    10  )
    11  
    12  //go:generate protoc -I. --go_out=paths=source_relative:. errors.proto
    13  
    14  func (e *Error) Error() string {
    15  	b, _ := json.Marshal(e)
    16  	return string(b)
    17  }
    18  
    19  // New generates a custom error.
    20  func New(id, detail string, code int32) error {
    21  	return &Error{
    22  		Id:     id,
    23  		Code:   code,
    24  		Detail: detail,
    25  		Status: http.StatusText(int(code)),
    26  	}
    27  }
    28  
    29  // Parse tries to parse a JSON string into an error. If that
    30  // fails, it will set the given string as the error detail.
    31  func Parse(err string) *Error {
    32  	e := new(Error)
    33  	errr := json.Unmarshal([]byte(err), e)
    34  	if errr != nil {
    35  		e.Detail = err
    36  	}
    37  	return e
    38  }
    39  
    40  // BadRequest generates a 400 error.
    41  func BadRequest(id, format string, a ...interface{}) error {
    42  	return &Error{
    43  		Id:     id,
    44  		Code:   400,
    45  		Detail: fmt.Sprintf(format, a...),
    46  		Status: http.StatusText(400),
    47  	}
    48  }
    49  
    50  // Unauthorized generates a 401 error.
    51  func Unauthorized(id, format string, a ...interface{}) error {
    52  	return &Error{
    53  		Id:     id,
    54  		Code:   401,
    55  		Detail: fmt.Sprintf(format, a...),
    56  		Status: http.StatusText(401),
    57  	}
    58  }
    59  
    60  // Forbidden generates a 403 error.
    61  func Forbidden(id, format string, a ...interface{}) error {
    62  	return &Error{
    63  		Id:     id,
    64  		Code:   403,
    65  		Detail: fmt.Sprintf(format, a...),
    66  		Status: http.StatusText(403),
    67  	}
    68  }
    69  
    70  // NotFound generates a 404 error.
    71  func NotFound(id, format string, a ...interface{}) error {
    72  	return &Error{
    73  		Id:     id,
    74  		Code:   404,
    75  		Detail: fmt.Sprintf(format, a...),
    76  		Status: http.StatusText(404),
    77  	}
    78  }
    79  
    80  // MethodNotAllowed generates a 405 error.
    81  func MethodNotAllowed(id, format string, a ...interface{}) error {
    82  	return &Error{
    83  		Id:     id,
    84  		Code:   405,
    85  		Detail: fmt.Sprintf(format, a...),
    86  		Status: http.StatusText(405),
    87  	}
    88  }
    89  
    90  // Timeout generates a 408 error.
    91  func Timeout(id, format string, a ...interface{}) error {
    92  	return &Error{
    93  		Id:     id,
    94  		Code:   408,
    95  		Detail: fmt.Sprintf(format, a...),
    96  		Status: http.StatusText(408),
    97  	}
    98  }
    99  
   100  // Conflict generates a 409 error.
   101  func Conflict(id, format string, a ...interface{}) error {
   102  	return &Error{
   103  		Id:     id,
   104  		Code:   409,
   105  		Detail: fmt.Sprintf(format, a...),
   106  		Status: http.StatusText(409),
   107  	}
   108  }
   109  
   110  // InternalServerError generates a 500 error.
   111  func InternalServerError(id, format string, a ...interface{}) error {
   112  	return &Error{
   113  		Id:     id,
   114  		Code:   500,
   115  		Detail: fmt.Sprintf(format, a...),
   116  		Status: http.StatusText(500),
   117  	}
   118  }
   119  
   120  // Equal tries to compare errors
   121  func Equal(err1 error, err2 error) bool {
   122  	verr1, ok1 := err1.(*Error)
   123  	verr2, ok2 := err2.(*Error)
   124  
   125  	if ok1 != ok2 {
   126  		return false
   127  	}
   128  
   129  	if !ok1 {
   130  		return err1 == err2
   131  	}
   132  
   133  	if verr1.Code != verr2.Code {
   134  		return false
   135  	}
   136  
   137  	return true
   138  }
   139  
   140  // FromError try to convert go error to *Error
   141  func FromError(err error) *Error {
   142  	if err == nil {
   143  		return nil
   144  	}
   145  	if verr, ok := err.(*Error); ok && verr != nil {
   146  		return verr
   147  	}
   148  
   149  	return Parse(err.Error())
   150  }
   151  
   152  // As finds the first error in err's chain that matches *Error
   153  func As(err error) (*Error, bool) {
   154  	if err == nil {
   155  		return nil, false
   156  	}
   157  	var merr *Error
   158  	if errors.As(err, &merr) {
   159  		return merr, true
   160  	}
   161  	return nil, false
   162  }
   163  
   164  func NewMultiError() *MultiError {
   165  	return &MultiError{
   166  		Errors: make([]*Error, 0),
   167  	}
   168  }
   169  
   170  func (e *MultiError) Append(err *Error) {
   171  	e.Errors = append(e.Errors, err)
   172  }
   173  
   174  func (e *MultiError) HasErrors() bool {
   175  	return len(e.Errors) > 0
   176  }
   177  
   178  func (e *MultiError) Error() string {
   179  	b, _ := json.Marshal(e)
   180  	return string(b)
   181  }