github.com/kaydxh/golang@v0.0.131/go/errors/error.grpc.go (about)

     1  /*
     2   *Copyright (c) 2022, kaydxh
     3   *
     4   *Permission is hereby granted, free of charge, to any person obtaining a copy
     5   *of this software and associated documentation files (the "Software"), to deal
     6   *in the Software without restriction, including without limitation the rights
     7   *to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     8   *copies of the Software, and to permit persons to whom the Software is
     9   *furnished to do so, subject to the following conditions:
    10   *
    11   *The above copyright notice and this permission notice shall be included in all
    12   *copies or substantial portions of the Software.
    13   *
    14   *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    15   *IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    16   *FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    17   *AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    18   *LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    19   *OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    20   *SOFTWARE.
    21   */
    22  package errors
    23  
    24  import (
    25  	"errors"
    26  	"fmt"
    27  	"strconv"
    28  	"strings"
    29  
    30  	"google.golang.org/genproto/googleapis/rpc/errdetails"
    31  	"google.golang.org/grpc/codes"
    32  	"google.golang.org/grpc/status"
    33  )
    34  
    35  func FromError(err error) (s *status.Status, ok bool) {
    36  	s, ok = status.FromError(err)
    37  	if ok {
    38  		return s, ok
    39  	}
    40  	var gRPCStatus interface {
    41  		GRPCStatus() *status.Status
    42  	}
    43  	if errors.As(err, &gRPCStatus) {
    44  		s = gRPCStatus.GRPCStatus()
    45  		//ok = true
    46  		ok = s != nil
    47  	}
    48  	return s, ok
    49  }
    50  
    51  func ErrorToCodeString(err error) string {
    52  	if err == nil {
    53  		return codes.OK.String()
    54  	}
    55  
    56  	s, ok := FromError(err)
    57  	if !ok {
    58  		return err.Error()
    59  	}
    60  	codeString := s.Code().String()
    61  	for _, detail := range s.Details() {
    62  		switch detail := detail.(type) {
    63  		case *errdetails.ErrorInfo:
    64  			if detail.GetReason() != "" {
    65  				codeString = detail.GetReason()
    66  			}
    67  		}
    68  	}
    69  
    70  	return codeString
    71  }
    72  
    73  // Error Message
    74  func ErrorToString(err error) string {
    75  	if err == nil {
    76  		return codes.OK.String()
    77  	}
    78  
    79  	s, ok := FromError(err)
    80  	if !ok {
    81  		return err.Error()
    82  	}
    83  	return s.Message()
    84  }
    85  
    86  func ErrorToCode(err error) codes.Code {
    87  	if err == nil {
    88  		return codes.OK
    89  	}
    90  
    91  	s, ok := FromError(err)
    92  	if !ok {
    93  		return codes.Unknown
    94  	}
    95  
    96  	return s.Code()
    97  }
    98  
    99  func Errorf(code interface{}, format string, a ...interface{}) error {
   100  	c, ok := code.(codes.Code)
   101  	if !ok {
   102  		c = codes.Unknown
   103  		num, err := strconv.Atoi(fmt.Sprintf("%d", code))
   104  		if err == nil {
   105  			c = codes.Code(num)
   106  		}
   107  	}
   108  
   109  	if c == codes.OK {
   110  		return nil
   111  	}
   112  
   113  	var message string
   114  	codeStringer, ok := code.(fmt.Stringer)
   115  	if ok {
   116  		message = strings.ReplaceAll(codeStringer.String(), "__", ".")
   117  	} else {
   118  		message = c.String()
   119  	}
   120  	s := status.New(c, fmt.Sprintf(format, a...))
   121  	if s.Code() != codes.OK && message != "" {
   122  		detail, err := s.WithDetails(&errdetails.ErrorInfo{
   123  			Reason: message,
   124  		})
   125  		if err == nil {
   126  			// replace new status with reason
   127  			s = detail
   128  		}
   129  	}
   130  
   131  	return s.Err()
   132  }
   133  
   134  func Errore(errlist ...error) error {
   135  	return NewAggregate(errlist)
   136  }