11package errors
22
3- import "errors"
3+ import (
4+ "errors"
5+ )
46
57var (
68 helpers []Helper
@@ -13,74 +15,70 @@ 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+ default :
50+ return err
51+ }
52+ // TODO: lookup via Cause interface recursively on error
53+ }
54+
3955// HasType is a helper function that will recurse up from the root error and check that the provided type
4056// is present using an equality check
4157func 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 {
49- return true
58+ switch t := err .(type ) {
59+ case Chain :
60+ for i := len (t ) - 1 ; i >= 0 ; i -- {
61+ for j := 0 ; j < len (t [i ].Types ); j ++ {
62+ if t [i ].Types [j ] == typ {
63+ return true
64+ }
5065 }
5166 }
5267 }
5368 return false
5469}
5570
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
71+ // LookupTag recursively searches for the provided tag and returns it's value or nil
72+ func LookupTag (err error , key string ) interface {} {
73+ switch t := err .(type ) {
74+ case Chain :
75+ for i := len (t ) - 1 ; i >= 0 ; i -- {
76+ for j := 0 ; j < len (t [i ].Tags ); j ++ {
77+ if t [i ].Tags [j ].Key == key {
78+ return t [i ].Tags [j ].Value
79+ }
80+ }
7681 }
77- // already extracted error
78- return w .Err == errType
7982 }
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 ), "" )
83+ return nil
8684}
0 commit comments