-
Notifications
You must be signed in to change notification settings - Fork 47
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: wrap parsing errors into ErrInvalidCid #150
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a test or two would be nice
Is the custom Is
necessary here? The Unwrap
should be enough for errors.Is
to work shouldn't it?
It's a shame we're not at minimum of Go 1.20 because fmt.Errorf("%w: %w", ErrInvalidCid, err)
would be an excellent pattern to avoid the additional code here, ErrInvalidCid
could just be an errors.New("invalid cid")
.
Yes, it is necessary. You can try running the test I just added without the
Yes, I do agree that the multiple wrapping in Go 1.20 would solve much of the hassle and be easier. Perhaps when we finally move to Go 1.20 we can change this, but then it will be a breaking change as |
c480125
to
65e3baa
Compare
See fc27a0c which you can pull in or reimplement yourself which changes this away from pointers. An error only needs to satisfy I'll see if I can get some more experienced gophers to weigh in in case I'm talking out of my butt here. |
I'd like to propose a simpler style of wrapping all together. It doesn't look like var (
ErrInvalidCid = errors.New("invalid cid")
ErrCidTooShort = fmt.Errorf("%w: cid too short", ErrInvalidCid)
) You'll typically find examples where the Whenever you want to return a func funcThatReturnsCidTooShort() error {
return ErrCidTooShort
} You can still check it's an err := funcThatReturnsCidTooShort()
errors.Is(err, ErrInvalidCid) {
// do whatever
} A nice side affect of the way we declared the error variables is that this creates a nice UX when using the errors. You don't need to instantiate a struct and pass it to You can do the same thing for one off func funcThatReturnsWrappedErrInvalidCid() error {
err := errors.New("some other error from somewhere else")
return fmt.Errorf("%w: %s", ErrInvalidCid, err)
} Here's a golang playground that implements what I just described. Playground is for 1.19. https://go.dev/play/p/zrCM0aQthTO?v=goprev package main
import (
"errors"
"fmt"
)
var (
ErrInvalidCid = errors.New("invalid cid")
ErrCidTooShort = fmt.Errorf("%w: cid too short", ErrInvalidCid)
)
func main() {
err1 := funcThatReturnsCidTooShort()
if errors.Is(err1, ErrInvalidCid) {
fmt.Printf("err1 is an ErrInvalidCid, %s\n", err1) // Prints "err1 is an ErrInvalidCid, invalid cid: cid too short"
}
err2 := funcThatReturnsWrappedErrInvalidCid()
if errors.Is(err2, ErrInvalidCid) {
fmt.Printf("err2 is an ErrInvalidCid, %s\n", err2) // Prints "err2 is an ErrInvalidCid, invalid cid: some other error from somewhere else"
}
}
func funcThatReturnsCidTooShort() error {
return ErrCidTooShort
}
func funcThatReturnsWrappedErrInvalidCid() error {
err := errors.New("some other error from somewhere else")
return fmt.Errorf("%w: %s", ErrInvalidCid, err)
} |
I just saw Rod's comment about this. This should work since go 1.13 no? I feel dumb now for writing out this whole thing and then realizing you guys might have already dismissed this because of the go version. Whoops 🤷. I see that go 1.20 supports wrapping of multiple errors, as Rod already pointed out. What is the reason that the code below doesn't work? Is it if return fmt.Errorf("%w, %s", ErrInvalidCid, err) UpdateSo yeah, if |
All of the cases where there's currently this: Same reason |
This might make sense. In ipfs/go-libipfs/pull/205, the usage is: errors.Is(err, &cid.ErrInvalidCid{}) {
...
} If we don't wait for multiple wrapping, then the above breaks when multiple wrapping is implemented. We could implement a |
Conversation here about |
Yeah okay, I see how this goes in circles back to implementing |
@rvagg what you propose is also fine, I just wanted to understand the reasoning behind it. I applied your commit.
@kylehuntsman yes, it breaks if we implement multiple wrapping here and release it as a patch release. If we do a 0.X release it should be fine to say there's a breaking change. I wouldn't consider that the most important piece right now. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor comments otherwise LGTM
c4c0f33
to
5c40574
Compare
20238df
to
901dee9
Compare
901dee9
to
343fe14
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for jumping through the hoops @hacdias, sorry for the pile-on, we're at the bottom of the stack so it's nice to get this RIGHT!
Let's bump a 0.4.0 for this, it's technically breaking because it removes the ability to do things like if err == mh.ErrInvalidMultihash {}
which would work with the current version. There's probably a bunch of other sentinel errors under here too, like mbase.ErrUnsupportedEncoding
.
0e0a623
to
c764ccc
Compare
Suggested version: Changes in diff --git a/go.mod b/go.mod
index 44e2a51..c06cc5c 100644
--- a/go.mod
+++ b/go.mod
@@ -13,8 +13,8 @@ require (
github.com/mr-tron/base58 v1.2.0 // indirect
github.com/multiformats/go-base32 v0.0.3 // indirect
github.com/multiformats/go-base36 v0.1.0 // indirect
- golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf // indirect
- golang.org/x/sys v0.0.0-20210309074719-68d13333faf2 // indirect
+ golang.org/x/crypto v0.1.0 // indirect
+ golang.org/x/sys v0.1.0 // indirect
)
-go 1.18
+go 1.19
Cutting a Release (and modifying non-markdown files)This PR is modifying both Automatically created GitHub ReleaseA draft GitHub Release has been created. |
This PR wraps the parsing errors into
ErrInvalidCid
, a new custom error type I added. This allows depends of this package to test if the error they got includes a wrapped CID parsing error viaerrors.Is
.