Implement Wrapper interface for baseError
I've gone ahead and added Unwrap on baseError in order to implement the Wrapper interface for go.1.13's error as well as xerror so that clients of aws-sdk-go can utilise errors.Is and errors.As with the awserror package.
This comes from the idea #2820
I left OrigErr for backwards compatibility.
@jasdel good catch. I didn't think about the error structs that had embedded interfaces, which doesn't make this useful for the other error types.
I'll take care on extending this, and writing a unit test for it.
Any update on this? I'd also like to see this.
One potential issue is that batched errors will result in infinite looping. The following program shows that recursive unwrapping will never terminate:
package main
import (
"errors"
"fmt"
"github.com/aws/aws-sdk-go/aws/awserr"
)
func main() {
base1 := errors.New("base 1")
base2 := errors.New("base 2")
var err awserr.Error = awserr.NewBatchError("mycode", "something died", []error{base1, base2})
for i := 0; i < 20; i++ {
fmt.Println(err)
err = err.OrigErr().(awserr.Error)
}
fmt.Println(err)
}
will print
mycode: something died
caused by: base 1
base 2
BatchedErrors: multiple errors occurred
caused by: base 1
base 2
BatchedErrors: multiple errors occurred
caused by: base 1
base 2
<snip many more>
This causes the built-in functions like errors.Is to enter an infinite loop when tested with a simple Unwrap implementation that returns OrigErr() (as currently proposed by this PR):
package main
import (
"errors"
"fmt"
"github.com/aws/aws-sdk-go/aws/awserr"
)
func main() {
base1 := errors.New("base 1")
base2 := errors.New("base 2")
var err awserr.Error = awserr.NewBatchError("mycode", "something died", []error{base1, base2})
// The following code enters an infinite loop:
fmt.Println(errors.Is(err, base1))
}
Hi @james-johnston-thumbtack this work is still outstanding. We've implemented this feature for the v2 developer preview SDK in aws/[email protected]. The implementation of batchError doesn't implement the Unwrap method for the reason you specified. An alternate Errs method was exposed.
In the v2 SDK implementing this feature was a bit easier because we could take more liberties with breaking changes to improve the experience, especially with regards to batched errors behavior.
Wanted to call out that the AWS SDK for Go v2 has solved this problem from the start. It supports errors.Unwrap, and errors.As for all error types.
We have noticed this issue has not received attention in 1 year. We will close this issue for now. If you think this is in error, please feel free to comment and reopen the issue.