hashicorp / go-multierror

A Go (golang) package for representing a list of errors as a single error.
Mozilla Public License 2.0
2.3k stars 123 forks source link

Support Go 1.13 errors.As/Is/Unwrap functionality #35

Closed mitchellh closed 4 years ago

mitchellh commented 4 years ago

The primary mechanism that enables this functionality is making Unwrap on the top-level Error return a new "chain" structure that uses state to keep track of the current error.

The chain implements errors.Is/As so that it compares to that current underlying error. And it implements Unwrap to move on to the next error.

A well-formed program using errors.Is/As/Unwrap exclusively will behave correctly with go-multierror in this case without dropping any errors. Direct comparisons such as Unwrap() == myErr will not work because we wrap in a chain. The user has to do errors.Is(err, myErr) which is the right thing to do anyways.

When Unwrap is called on a top-level Error, we create a shallow copy of the errors so that you can continue using Error (modifying it, potentially in-place). There is a slight cost to this but it felt weird that calling Unwrap would share the same underlying data and cause potential data races. I think this is unlikely, but its also very unlikely the performance cost of the shallow copy of errors will matter either.

hashicorp-cla commented 4 years ago

CLA assistant check
All committers have signed the CLA.

felixge commented 4 years ago

I'm still reviewing and thinking through edge cases.

Here is a test case for one of them that might be worth including (the implementation already passes it):

https://github.com/felixge/go-multierror/commit/9b44b21f121fb1f033eded9b035d48a957e9df41

mitchellh commented 4 years ago

I'm still reviewing and thinking through edge cases.

Here is a test case for one of them that might be worth including (the implementation already passes it):

felixge@9b44b21

Cherry picked this commit and added the test. Thanks.