github.com/sagernet/sing@v0.4.0-beta.19.0.20240518125136-f67a0988a636/common/exceptions/inner.go (about) 1 package exceptions 2 3 import "github.com/sagernet/sing/common" 4 5 type HasInnerError interface { 6 Unwrap() error 7 } 8 9 func Unwrap(err error) error { 10 for { 11 inner, ok := err.(HasInnerError) 12 if !ok { 13 break 14 } 15 innerErr := inner.Unwrap() 16 if innerErr == nil { 17 break 18 } 19 err = innerErr 20 } 21 return err 22 } 23 24 func Cast[T any](err error) (T, bool) { 25 if err == nil { 26 return common.DefaultValue[T](), false 27 } 28 29 for { 30 interfaceError, isInterface := err.(T) 31 if isInterface { 32 return interfaceError, true 33 } 34 switch x := err.(type) { 35 case interface{ Unwrap() error }: 36 err = x.Unwrap() 37 if err == nil { 38 return common.DefaultValue[T](), false 39 } 40 case interface{ Unwrap() []error }: 41 for _, innerErr := range x.Unwrap() { 42 if interfaceError, isInterface = Cast[T](innerErr); isInterface { 43 return interfaceError, true 44 } 45 } 46 return common.DefaultValue[T](), false 47 default: 48 return common.DefaultValue[T](), false 49 } 50 } 51 }