github.com/gogf/gf/v2@v2.7.4/errors/gerror/gerror_api_stack.go (about) 1 // Copyright GoFrame 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 8 9 import ( 10 "errors" 11 "runtime" 12 ) 13 14 // stack represents a stack of program counters. 15 type stack []uintptr 16 17 const ( 18 // maxStackDepth marks the max stack depth for error back traces. 19 maxStackDepth = 64 20 ) 21 22 // Cause returns the root cause error of `err`. 23 func Cause(err error) error { 24 if err == nil { 25 return nil 26 } 27 if e, ok := err.(ICause); ok { 28 return e.Cause() 29 } 30 if e, ok := err.(IUnwrap); ok { 31 return Cause(e.Unwrap()) 32 } 33 return err 34 } 35 36 // Stack returns the stack callers as string. 37 // It returns the error string directly if the `err` does not support stacks. 38 func Stack(err error) string { 39 if err == nil { 40 return "" 41 } 42 if e, ok := err.(IStack); ok { 43 return e.Stack() 44 } 45 return err.Error() 46 } 47 48 // Current creates and returns the current level error. 49 // It returns nil if current level error is nil. 50 func Current(err error) error { 51 if err == nil { 52 return nil 53 } 54 if e, ok := err.(ICurrent); ok { 55 return e.Current() 56 } 57 return err 58 } 59 60 // Unwrap returns the next level error. 61 // It returns nil if current level error or the next level error is nil. 62 func Unwrap(err error) error { 63 if err == nil { 64 return nil 65 } 66 if e, ok := err.(IUnwrap); ok { 67 return e.Unwrap() 68 } 69 return nil 70 } 71 72 // HasStack checks and reports whether `err` implemented interface `gerror.IStack`. 73 func HasStack(err error) bool { 74 _, ok := err.(IStack) 75 return ok 76 } 77 78 // Equal reports whether current error `err` equals to error `target`. 79 // Please note that, in default comparison logic for `Error`, 80 // the errors are considered the same if both the `code` and `text` of them are the same. 81 func Equal(err, target error) bool { 82 if err == target { 83 return true 84 } 85 if e, ok := err.(IEqual); ok { 86 return e.Equal(target) 87 } 88 if e, ok := target.(IEqual); ok { 89 return e.Equal(err) 90 } 91 return false 92 } 93 94 // Is reports whether current error `err` has error `target` in its chaining errors. 95 // There's similar function HasError which is designed and implemented early before errors.Is of go stdlib. 96 // It is now alias of errors.Is of go stdlib, to guarantee the same performance as go stdlib. 97 func Is(err, target error) bool { 98 return errors.Is(err, target) 99 } 100 101 // HasError performs as Is. 102 // This function is designed and implemented early before errors.Is of go stdlib. 103 // Deprecated: use Is instead. 104 func HasError(err, target error) bool { 105 return errors.Is(err, target) 106 } 107 108 // callers returns the stack callers. 109 // Note that it here just retrieves the caller memory address array not the caller information. 110 func callers(skip ...int) stack { 111 var ( 112 pcs [maxStackDepth]uintptr 113 n = 3 114 ) 115 if len(skip) > 0 { 116 n += skip[0] 117 } 118 return pcs[:runtime.Callers(n, pcs[:])] 119 }