github.com/yaoapp/kun@v0.9.0/exception/exception.go (about)

     1  package exception
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"runtime/debug"
     7  
     8  	"github.com/TylerBrock/colorjson"
     9  	"github.com/fatih/color"
    10  )
    11  
    12  // Exception the Exception type
    13  type Exception struct {
    14  	Message string      `json:"message"`
    15  	Code    int         `json:"code"`
    16  	Context interface{} `json:"context"`
    17  }
    18  
    19  // New Create a new exception instance
    20  func New(message string, code int, args ...interface{}) *Exception {
    21  	content := fmt.Sprintf(message, args...)
    22  	return &Exception{
    23  		Message: content,
    24  		Code:    code,
    25  	}
    26  }
    27  
    28  // Err Create an exception instance from the error
    29  func Err(err error, code int) *Exception {
    30  	return &Exception{
    31  		Message: err.Error(),
    32  		Code:    code,
    33  	}
    34  }
    35  
    36  // Catch Exception catch and recovered
    37  func Catch(recovered interface{}) error {
    38  	if recovered == nil {
    39  		return nil
    40  	} else if err, ok := recovered.(string); ok {
    41  		return fmt.Errorf("%s", err)
    42  	} else if err, ok := recovered.(Exception); ok {
    43  		return fmt.Errorf("%s", err.Message)
    44  	} else if err, ok := recovered.(*Exception); ok {
    45  		return fmt.Errorf("%s", err.Message)
    46  	}
    47  	return fmt.Errorf("%s", recovered)
    48  }
    49  
    50  // CatchPrint Catch the exception and print it
    51  func CatchPrint() {
    52  	if r := recover(); r != nil {
    53  		switch r.(type) {
    54  		case *Exception:
    55  			color.Red(r.(*Exception).Message)
    56  			r.(*Exception).Print()
    57  			break
    58  		case string:
    59  			color.Red(r.(string))
    60  			break
    61  		case error:
    62  			color.Red(r.(error).Error())
    63  			break
    64  		default:
    65  			color.Red("%#v\n", r)
    66  		}
    67  	}
    68  }
    69  
    70  // CatchDebug Catch the exception and print debug info
    71  func CatchDebug() {
    72  	if r := recover(); r != nil {
    73  		switch r.(type) {
    74  		case *Exception:
    75  			color.Red(r.(*Exception).Message)
    76  			r.(*Exception).Print()
    77  			break
    78  		case string:
    79  			color.Red(r.(string))
    80  			break
    81  		case error:
    82  			color.Red(r.(error).Error())
    83  			break
    84  		default:
    85  			color.Red("%#v\n", r)
    86  		}
    87  
    88  		fmt.Println("stacktrace from panic: \n" + string(debug.Stack()))
    89  	}
    90  }
    91  
    92  // Ctx Add the context for the exception.
    93  func (exception *Exception) Ctx(context interface{}) *Exception {
    94  	exception.Context = context
    95  	return exception
    96  }
    97  
    98  // Print print the exception
    99  func (exception Exception) Print() {
   100  	f := colorjson.NewFormatter()
   101  	f.Indent = 2
   102  	var res interface{}
   103  	txt, _ := json.Marshal(exception)
   104  	json.Unmarshal(txt, &res)
   105  	s, _ := colorjson.Marshal(res)
   106  	fmt.Println(string(s))
   107  }
   108  
   109  // Throw Throw the exception and terminal progress.
   110  func (exception Exception) Throw() {
   111  	panic(exception)
   112  }
   113  
   114  // String interface
   115  func (exception Exception) String() string {
   116  	txt, _ := json.Marshal(exception)
   117  	return string(txt)
   118  }