github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/service/errors/errors.go (about)

     1  // Licensed under the Apache License, Version 2.0 (the "License");
     2  // you may not use this file except in compliance with the License.
     3  // You may obtain a copy of the License at
     4  //
     5  //     https://www.apache.org/licenses/LICENSE-2.0
     6  //
     7  // Unless required by applicable law or agreed to in writing, software
     8  // distributed under the License is distributed on an "AS IS" BASIS,
     9  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    10  // See the License for the specific language governing permissions and
    11  // limitations under the License.
    12  //
    13  // Original source: github.com/micro/go-micro/v3/errors/errors.go
    14  
    15  // Package errors provides a way to return detailed information
    16  // for an RPC request error. The error is normally JSON encoded.
    17  package errors
    18  
    19  import (
    20  	"encoding/json"
    21  	"fmt"
    22  	"net/http"
    23  )
    24  
    25  type Error struct {
    26  	Id     string `json:"id"`
    27  	Code   int32  `json:"code"`
    28  	Detail string `json:"detail"`
    29  	Status string `json:"status"`
    30  }
    31  
    32  func (e *Error) Error() string {
    33  	b, _ := json.Marshal(e)
    34  	return string(b)
    35  }
    36  
    37  // New generates a custom error.
    38  func New(id, detail string, code int32) error {
    39  	return &Error{
    40  		Id:     id,
    41  		Code:   code,
    42  		Detail: detail,
    43  		Status: http.StatusText(int(code)),
    44  	}
    45  }
    46  
    47  // FromError try to convert go error to *Error
    48  func FromError(err error) *Error {
    49  	if err == nil {
    50  		return nil
    51  	}
    52  	if verr, ok := err.(*Error); ok && verr != nil {
    53  		return verr
    54  	}
    55  
    56  	return Parse(err.Error())
    57  }
    58  
    59  // Parse tries to parse a JSON string into an error. If that
    60  // fails, it will set the given string as the error detail.
    61  func Parse(err string) *Error {
    62  	e := new(Error)
    63  	errr := json.Unmarshal([]byte(err), e)
    64  	if errr != nil {
    65  		e.Detail = err
    66  	}
    67  	return e
    68  }
    69  
    70  // BadRequest generates a 400 error.
    71  func BadRequest(id, format string, a ...interface{}) error {
    72  	return &Error{
    73  		Id:     id,
    74  		Code:   400,
    75  		Detail: fmt.Sprintf(format, a...),
    76  		Status: http.StatusText(400),
    77  	}
    78  }
    79  
    80  // Unauthorized generates a 401 error.
    81  func Unauthorized(id, format string, a ...interface{}) error {
    82  	return &Error{
    83  		Id:     id,
    84  		Code:   401,
    85  		Detail: fmt.Sprintf(format, a...),
    86  		Status: http.StatusText(401),
    87  	}
    88  }
    89  
    90  // Forbidden generates a 403 error.
    91  func Forbidden(id, format string, a ...interface{}) error {
    92  	return &Error{
    93  		Id:     id,
    94  		Code:   403,
    95  		Detail: fmt.Sprintf(format, a...),
    96  		Status: http.StatusText(403),
    97  	}
    98  }
    99  
   100  // NotFound generates a 404 error.
   101  func NotFound(id, format string, a ...interface{}) error {
   102  	return &Error{
   103  		Id:     id,
   104  		Code:   404,
   105  		Detail: fmt.Sprintf(format, a...),
   106  		Status: http.StatusText(404),
   107  	}
   108  }
   109  
   110  // MethodNotAllowed generates a 405 error.
   111  func MethodNotAllowed(id, format string, a ...interface{}) error {
   112  	return &Error{
   113  		Id:     id,
   114  		Code:   405,
   115  		Detail: fmt.Sprintf(format, a...),
   116  		Status: http.StatusText(405),
   117  	}
   118  }
   119  
   120  // Timeout generates a 408 error.
   121  func Timeout(id, format string, a ...interface{}) error {
   122  	return &Error{
   123  		Id:     id,
   124  		Code:   408,
   125  		Detail: fmt.Sprintf(format, a...),
   126  		Status: http.StatusText(408),
   127  	}
   128  }
   129  
   130  // Conflict generates a 409 error.
   131  func Conflict(id, format string, a ...interface{}) error {
   132  	return &Error{
   133  		Id:     id,
   134  		Code:   409,
   135  		Detail: fmt.Sprintf(format, a...),
   136  		Status: http.StatusText(409),
   137  	}
   138  }
   139  
   140  // InternalServerError generates a 500 error.
   141  func InternalServerError(id, format string, a ...interface{}) error {
   142  	return &Error{
   143  		Id:     id,
   144  		Code:   500,
   145  		Detail: fmt.Sprintf(format, a...),
   146  		Status: http.StatusText(500),
   147  	}
   148  }
   149  
   150  // NotImplemented generates a 501 error
   151  func NotImplemented(id, format string, a ...interface{}) error {
   152  	return &Error{
   153  		Id:     id,
   154  		Code:   501,
   155  		Detail: fmt.Sprintf(format, a...),
   156  		Status: http.StatusText(501),
   157  	}
   158  }
   159  
   160  // BadGateway generates a 502 error
   161  func BadGateway(id, format string, a ...interface{}) error {
   162  	return &Error{
   163  		Id:     id,
   164  		Code:   502,
   165  		Detail: fmt.Sprintf(format, a...),
   166  		Status: http.StatusText(502),
   167  	}
   168  }
   169  
   170  // ServiceUnavailable generates a 503 error
   171  func ServiceUnavailable(id, format string, a ...interface{}) error {
   172  	return &Error{
   173  		Id:     id,
   174  		Code:   503,
   175  		Detail: fmt.Sprintf(format, a...),
   176  		Status: http.StatusText(503),
   177  	}
   178  }
   179  
   180  // GatewayTimeout generates a 504 error
   181  func GatewayTimeout(id, format string, a ...interface{}) error {
   182  	return &Error{
   183  		Id:     id,
   184  		Code:   504,
   185  		Detail: fmt.Sprintf(format, a...),
   186  		Status: http.StatusText(504),
   187  	}
   188  }
   189  
   190  // Equal tries to compare errors
   191  func Equal(err1 error, err2 error) bool {
   192  	verr1, ok1 := err1.(*Error)
   193  	verr2, ok2 := err2.(*Error)
   194  
   195  	if ok1 != ok2 {
   196  		return false
   197  	}
   198  
   199  	if !ok1 {
   200  		return err1 == err2
   201  	}
   202  
   203  	if verr1.Code != verr2.Code {
   204  		return false
   205  	}
   206  
   207  	return true
   208  }