My limited understanding of Go error "kinds" is as follows: 1. error values of arbitrary type, where the type doesn't matter: such as returned by errors.New("D'OH!"). 2. sentinel(?) errors, such as io.EOF: when comparing against the same error instance. 3. wrapped errors, where the type of the wrapper (type) doesn't matter: such as created by fmt.Errorf("...%w", err) 4. ... Now, in some situations I would like to use typed errors which additionally wrap underlying errors. Sentinel (2) errors don't work, as due to the wrapping there would be an open number of different values with no chance of classification. And (3) doesn't allow individual typing either.
In order to create individual error types that additionally wrap underlying one can either write the same following boilerplate over and over again, or alternatively use embedding in addition with method propagation. For instance: type WrappingError struct { msg string err error } func (w *WrappingError) Error() string { return w.msg } func (w *WrappingError) Unwrap() error { return w.err } type AErr struct{ WrappingError } type BErr struct{ WrappingError } ...this gives individual error types AErr and BErr without having to copy-and-paste everything everytime a new wrapping error type is needed. Now with generics I understand that I can't do anything about the type AErr ... boilerplate. However, what about at least making creating new typed wrapping errors less of a boilerplate pain? Naively, I tried... func New[T ~struct{ WrappingError }](msg string, err error) error { e := T{WrappingError{msg: msg, err: err}} return &e } ...but this get's rejected in Go 1.19: * cannot use &e (value of type *T) as type error in return statement: *T does not implement error (type *T is pointer to type parameter, not type parameter)* I would have liked to use it like this: err := New[AErr]("this is an error", errors.New("foo")) Any idea how this could be coded differently to somehow achieve the goal of reducing boilerplate pain when it comes to typed wrapping errors? Or is this a perfect example of attempting to throw Go generics at something generics are not supposed to support...? Example on the "Better Go Playground": https://goplay.tools/snippet/NNPL5m5VekG -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/41217af0-4780-45b5-b913-fd010e34e98dn%40googlegroups.com.