github.com/gogf/gf@v1.16.9/errors/gerror/gerror.go (about)

     1  // Copyright GoFrame gf Author(https://goframe.org). All Rights Reserved.
     2  //
     3  // This Source Code Form is subject to the terms of the MIT License.
     4  // If a copy of the MIT was not distributed with this file,
     5  // You can obtain one at https://github.com/gogf/gf.
     6  
     7  // Package gerror provides simple functions to manipulate errors.
     8  //
     9  // Very note that, this package is quite a base package, which should not import extra
    10  // packages except standard packages, to avoid cycle imports.
    11  package gerror
    12  
    13  import (
    14  	"fmt"
    15  	"github.com/gogf/gf/errors/gcode"
    16  )
    17  
    18  // apiCode is the interface for Code feature.
    19  type apiCode interface {
    20  	Error() string
    21  	Code() gcode.Code
    22  }
    23  
    24  // apiStack is the interface for Stack feature.
    25  type apiStack interface {
    26  	Error() string
    27  	Stack() string
    28  }
    29  
    30  // apiCause is the interface for Cause feature.
    31  type apiCause interface {
    32  	Error() string
    33  	Cause() error
    34  }
    35  
    36  // apiCurrent is the interface for Current feature.
    37  type apiCurrent interface {
    38  	Error() string
    39  	Current() error
    40  }
    41  
    42  // apiNext is the interface for Next feature.
    43  type apiNext interface {
    44  	Error() string
    45  	Next() error
    46  }
    47  
    48  // New creates and returns an error which is formatted from given text.
    49  func New(text string) error {
    50  	return &Error{
    51  		stack: callers(),
    52  		text:  text,
    53  		code:  gcode.CodeNil,
    54  	}
    55  }
    56  
    57  // Newf returns an error that formats as the given format and args.
    58  func Newf(format string, args ...interface{}) error {
    59  	return &Error{
    60  		stack: callers(),
    61  		text:  fmt.Sprintf(format, args...),
    62  		code:  gcode.CodeNil,
    63  	}
    64  }
    65  
    66  // NewSkip creates and returns an error which is formatted from given text.
    67  // The parameter <skip> specifies the stack callers skipped amount.
    68  func NewSkip(skip int, text string) error {
    69  	return &Error{
    70  		stack: callers(skip),
    71  		text:  text,
    72  		code:  gcode.CodeNil,
    73  	}
    74  }
    75  
    76  // NewSkipf returns an error that formats as the given format and args.
    77  // The parameter <skip> specifies the stack callers skipped amount.
    78  func NewSkipf(skip int, format string, args ...interface{}) error {
    79  	return &Error{
    80  		stack: callers(skip),
    81  		text:  fmt.Sprintf(format, args...),
    82  		code:  gcode.CodeNil,
    83  	}
    84  }
    85  
    86  // Wrap wraps error with text.
    87  // It returns nil if given err is nil.
    88  func Wrap(err error, text string) error {
    89  	if err == nil {
    90  		return nil
    91  	}
    92  	return &Error{
    93  		error: err,
    94  		stack: callers(),
    95  		text:  text,
    96  		code:  Code(err),
    97  	}
    98  }
    99  
   100  // Wrapf returns an error annotating err with a stack trace
   101  // at the point Wrapf is called, and the format specifier.
   102  // It returns nil if given <err> is nil.
   103  func Wrapf(err error, format string, args ...interface{}) error {
   104  	if err == nil {
   105  		return nil
   106  	}
   107  	return &Error{
   108  		error: err,
   109  		stack: callers(),
   110  		text:  fmt.Sprintf(format, args...),
   111  		code:  Code(err),
   112  	}
   113  }
   114  
   115  // WrapSkip wraps error with text.
   116  // It returns nil if given err is nil.
   117  // The parameter <skip> specifies the stack callers skipped amount.
   118  func WrapSkip(skip int, err error, text string) error {
   119  	if err == nil {
   120  		return nil
   121  	}
   122  	return &Error{
   123  		error: err,
   124  		stack: callers(skip),
   125  		text:  text,
   126  		code:  Code(err),
   127  	}
   128  }
   129  
   130  // WrapSkipf wraps error with text that is formatted with given format and args.
   131  // It returns nil if given err is nil.
   132  // The parameter <skip> specifies the stack callers skipped amount.
   133  func WrapSkipf(skip int, err error, format string, args ...interface{}) error {
   134  	if err == nil {
   135  		return nil
   136  	}
   137  	return &Error{
   138  		error: err,
   139  		stack: callers(skip),
   140  		text:  fmt.Sprintf(format, args...),
   141  		code:  Code(err),
   142  	}
   143  }
   144  
   145  // NewCode creates and returns an error that has error code and given text.
   146  func NewCode(code gcode.Code, text ...string) error {
   147  	errText := ""
   148  	if len(text) > 0 {
   149  		errText = text[0]
   150  	}
   151  	return &Error{
   152  		stack: callers(),
   153  		text:  errText,
   154  		code:  code,
   155  	}
   156  }
   157  
   158  // NewCodef returns an error that has error code and formats as the given format and args.
   159  func NewCodef(code gcode.Code, format string, args ...interface{}) error {
   160  	return &Error{
   161  		stack: callers(),
   162  		text:  fmt.Sprintf(format, args...),
   163  		code:  code,
   164  	}
   165  }
   166  
   167  // NewCodeSkip creates and returns an error which has error code and is formatted from given text.
   168  // The parameter <skip> specifies the stack callers skipped amount.
   169  func NewCodeSkip(code gcode.Code, skip int, text ...string) error {
   170  	errText := ""
   171  	if len(text) > 0 {
   172  		errText = text[0]
   173  	}
   174  	return &Error{
   175  		stack: callers(skip),
   176  		text:  errText,
   177  		code:  code,
   178  	}
   179  }
   180  
   181  // NewCodeSkipf returns an error that has error code and formats as the given format and args.
   182  // The parameter <skip> specifies the stack callers skipped amount.
   183  func NewCodeSkipf(code gcode.Code, skip int, format string, args ...interface{}) error {
   184  	return &Error{
   185  		stack: callers(skip),
   186  		text:  fmt.Sprintf(format, args...),
   187  		code:  code,
   188  	}
   189  }
   190  
   191  // WrapCode wraps error with code and text.
   192  // It returns nil if given err is nil.
   193  func WrapCode(code gcode.Code, err error, text ...string) error {
   194  	if err == nil {
   195  		return nil
   196  	}
   197  	errText := ""
   198  	if len(text) > 0 {
   199  		errText = text[0]
   200  	}
   201  	return &Error{
   202  		error: err,
   203  		stack: callers(),
   204  		text:  errText,
   205  		code:  code,
   206  	}
   207  }
   208  
   209  // WrapCodef wraps error with code and format specifier.
   210  // It returns nil if given <err> is nil.
   211  func WrapCodef(code gcode.Code, err error, format string, args ...interface{}) error {
   212  	if err == nil {
   213  		return nil
   214  	}
   215  	return &Error{
   216  		error: err,
   217  		stack: callers(),
   218  		text:  fmt.Sprintf(format, args...),
   219  		code:  code,
   220  	}
   221  }
   222  
   223  // WrapCodeSkip wraps error with code and text.
   224  // It returns nil if given err is nil.
   225  // The parameter <skip> specifies the stack callers skipped amount.
   226  func WrapCodeSkip(code gcode.Code, skip int, err error, text ...string) error {
   227  	if err == nil {
   228  		return nil
   229  	}
   230  	errText := ""
   231  	if len(text) > 0 {
   232  		errText = text[0]
   233  	}
   234  	return &Error{
   235  		error: err,
   236  		stack: callers(skip),
   237  		text:  errText,
   238  		code:  code,
   239  	}
   240  }
   241  
   242  // WrapCodeSkipf wraps error with code and text that is formatted with given format and args.
   243  // It returns nil if given err is nil.
   244  // The parameter <skip> specifies the stack callers skipped amount.
   245  func WrapCodeSkipf(code gcode.Code, skip int, err error, format string, args ...interface{}) error {
   246  	if err == nil {
   247  		return nil
   248  	}
   249  	return &Error{
   250  		error: err,
   251  		stack: callers(skip),
   252  		text:  fmt.Sprintf(format, args...),
   253  		code:  code,
   254  	}
   255  }
   256  
   257  // Code returns the error code of current error.
   258  // It returns CodeNil if it has no error code or it does not implements interface Code.
   259  func Code(err error) gcode.Code {
   260  	if err != nil {
   261  		if e, ok := err.(apiCode); ok {
   262  			return e.Code()
   263  		}
   264  	}
   265  	return gcode.CodeNil
   266  }
   267  
   268  // Cause returns the root cause error of <err>.
   269  func Cause(err error) error {
   270  	if err != nil {
   271  		if e, ok := err.(apiCause); ok {
   272  			return e.Cause()
   273  		}
   274  	}
   275  	return err
   276  }
   277  
   278  // Stack returns the stack callers as string.
   279  // It returns the error string directly if the <err> does not support stacks.
   280  func Stack(err error) string {
   281  	if err == nil {
   282  		return ""
   283  	}
   284  	if e, ok := err.(apiStack); ok {
   285  		return e.Stack()
   286  	}
   287  	return err.Error()
   288  }
   289  
   290  // Current creates and returns the current level error.
   291  // It returns nil if current level error is nil.
   292  func Current(err error) error {
   293  	if err == nil {
   294  		return nil
   295  	}
   296  	if e, ok := err.(apiCurrent); ok {
   297  		return e.Current()
   298  	}
   299  	return err
   300  }
   301  
   302  // Next returns the next level error.
   303  // It returns nil if current level error or the next level error is nil.
   304  func Next(err error) error {
   305  	if err == nil {
   306  		return nil
   307  	}
   308  	if e, ok := err.(apiNext); ok {
   309  		return e.Next()
   310  	}
   311  	return nil
   312  }