Switching on the type of an error
goerrors
I created a custom error struct, and I wanted to make it compatible with
errors.Is.
package main
import (
"fmt"
)
type MyError struct {
Source string
Type string
}
func (e MyError) Error() string {
return fmt.Sprintf("type(%s) from source(%s)", e.Type, e.Source)
}
Since errors.Is function must take parameter of err as error
interface, we can simple do err.(type) because the value will be always
error.
package main
// This will not work as intended
func (e MyError) Is(err error) bool {
switch err := err.(type) {
case MyError: // err.(type) is always `error` this will never match
return e.Source == err.Source && e.Type == err.Type
default:
return false
}
}
The trick is to cast it to an interface first, and then ask for the type.
package main
// This works as intended
func (e MyError) Is(err error) bool {
// Cast to interface{} and then ask for the type
switch err := err.(interface{}).(type) {
case MyError:
return e.Source == err.Source && e.Type == err.Type
default:
return false
}
}
I am fairly new to Go, so I am not sure if people prefer to use reflect package
using reflect.TypeOf(target), just tried to avoid such package I honestly don't
know the differences, just stick to strong-typing ways to deal with
strong-typing from my perspective.