When fixing #11, it was decided to make an exemption for comparisons and switches in Is methods. This works for errors that are atomic values, but some errors have more structure and need a more detailed comparison.
For example, for an error like
type ComplexError struct {
code int
message string
}
func (e *ComplexError) Error() string {
return fmt.Sprintf(%d: %s, e.code, e.message)
}
we may want to do more than just compare types in an Is method, we may want to assert the error's codes and message match as well:
func (e *ComplexError) Is(target error) bool {
terr, ok := target.(*ComplexError)
return ok && *e == *terr
}
If we want to provide an equivalence between errors of different types, we may also need to use the switch form of type assertion.
type AnotherComplexError {
code int
message []byte
}
func (e *AnotherComplexError) Error() string {
return fmt.Sprintf(%d: %s, e.code, e.message)
}
func (e *AnotherComplexError) Is(target error) bool {
switch terr := target.(type) {
case *AnotherComplexError:
return *e == *terr
case *ComplexError:
return e.code == terr.code && e.message == []byte(terr.message)
default:
false
}
}
with an appropriate method for *ComplexError as well.
Currently, both forms of type assertion are warned of by go-errorlint.