On Sun, Jun 19, 2022 at 11:11 PM TheDiveO <harald.albre...@gmx.net> wrote:
>
> if I understand the linked proposal correct then it is about wrapping 
> multiple errors. I'm unsure how this relates to my question about having 
> separate error types as to differentiate them, and each type always only 
> wraps a single error. How do I connect the dots?

It seemed like a similar concept to me.  Likely I misunderstood.  Apologies.

One way to write code similar to what you wrote above is

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 }

func New[T ~struct{ *WrappingError }](msg string, err error) error {
e := T{&WrappingError{msg: msg, err: err}}
return error(e)
}

Ian

> On Monday, June 20, 2022 at 7:49:29 AM UTC+2 Ian Lance Taylor wrote:
>>
>> On Sun, Jun 19, 2022 at 2:03 PM TheDiveO <harald....@gmx.net> wrote:
>> >
>> > My limited understanding of Go error "kinds" is as follows:
>> >
>> > error values of arbitrary type, where the type doesn't matter: such as 
>> > returned by errors.New("D'OH!").
>> > sentinel(?) errors, such as io.EOF: when comparing against the same error 
>> > instance.
>> > wrapped errors, where the type of the wrapper (type) doesn't matter: such 
>> > as created by fmt.Errorf("...%w", err)
>> > ...
>> >
>> > 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
>>
>> Related discussion at https://go.dev/issue/53435 which links to
>> several other related issues.
>>
>> Ian
>
> --
> 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/2c284149-7053-4f94-8903-3cfd7288a935n%40googlegroups.com.

-- 
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/CAOyqgcXHu-u7iEZXjq30g_NfUtSNPeRQ-WPOEibQxh%2BpESfvKw%40mail.gmail.com.

Reply via email to