11package errors
22
3- import "errors"
3+ import (
4+ "errors"
5+ )
46
57var (
68 helpers []Helper
@@ -13,74 +15,63 @@ func RegisterHelper(helper Helper) {
1315 helpers = append (helpers , helper )
1416}
1517
18+ // New creates an error with the provided text and automatically wraps it with line information.
19+ func New (s string ) Chain {
20+ return wrap (errors .New (s ), "" )
21+ }
22+
1623// Wrap encapsulates the error, stores a contextual prefix and automatically obtains
1724// a stack trace.
18- func Wrap (err error , prefix string ) ( w * Wrapped ) {
25+ func Wrap (err error , prefix string ) Chain {
1926 return wrap (err , prefix )
2027}
2128
22- func wrap (err error , prefix string ) (w * Wrapped ) {
29+ func wrap (err error , prefix string ) (c Chain ) {
2330 var ok bool
24- if w , ok = err .(* Wrapped ); ok {
25- w . Errors = append (w . Errors , newWrapped (err , prefix ))
31+ if c , ok = err .(Chain ); ok {
32+ c = append (c , newLink (err , prefix ))
2633 } else {
27- w = & Wrapped {
28- Errors : []* Wrapped {newWrapped (err , prefix )},
29- }
34+ c = Chain {newLink (err , prefix )}
3035 }
3136 for _ , h := range helpers {
32- if ! h (w , err ) {
37+ if ! h (c , err ) {
3338 break
3439 }
3540 }
3641 return
3742}
3843
44+ // Cause extracts and returns the root wrapped error (the naked error with no additional information
45+ func Cause (err error ) error {
46+ switch t := err .(type ) {
47+ case Chain :
48+ return t [0 ].Err
49+ case * Link :
50+ return t .Err
51+ default :
52+ return err
53+ }
54+ // TODO: lookup via Cause interface recursively on error
55+ }
56+
3957// HasType is a helper function that will recurse up from the root error and check that the provided type
4058// is present using an equality check
4159func HasType (err error , typ string ) bool {
42- w , ok := err .(* Wrapped )
43- if ! ok {
44- return false
45- }
46- for i := len (w .Errors ) - 1 ; i >= 0 ; i -- {
47- for j := 0 ; j < len (w .Errors [i ].Types ); j ++ {
48- if w .Errors [i ].Types [j ] == typ {
60+ switch t := err .(type ) {
61+ case Chain :
62+ for i := len (t ) - 1 ; i >= 0 ; i -- {
63+ for j := 0 ; j < len (t [i ].Types ); j ++ {
64+ if t [i ].Types [j ] == typ {
65+ return true
66+ }
67+ }
68+ }
69+ case * Link :
70+ for i := 0 ; i < len (t .Types ); i ++ {
71+ if t .Types [i ] == typ {
4972 return true
5073 }
5174 }
5275 }
5376 return false
5477}
55-
56- // Cause extracts and returns the root error
57- func Cause (err error ) error {
58- if w , ok := err .(* Wrapped ); ok {
59- // if root level error
60- if len (w .Errors ) > 0 {
61- return w .Errors [0 ]
62- }
63- // already extracted error
64- return w
65- }
66- return err
67- }
68-
69- // IsErr will fetch the root error, and check the original error against the provided type
70- // eg. errors.IsErr(io.EOF)
71- func IsErr (err , errType error ) bool {
72- if w , ok := err .(* Wrapped ); ok {
73- // if root level error
74- if len (w .Errors ) > 0 {
75- return w .Errors [0 ].Err == errType
76- }
77- // already extracted error
78- return w .Err == errType
79- }
80- return err == errType
81- }
82-
83- // New creates an error with the provided text and automatically wraps it with line information.
84- func New (s string ) * Wrapped {
85- return wrap (errors .New (s ), "" )
86- }
0 commit comments