-
Notifications
You must be signed in to change notification settings - Fork 46
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
Global error refactor and docs #339
Conversation
Codecov Report
@@ Coverage Diff @@
## master #339 +/- ##
========================================
- Coverage 70.4% 69.1% -1.3%
========================================
Files 131 129 -2
Lines 6208 6209 +1
========================================
- Hits 4374 4295 -79
- Misses 1414 1474 +60
- Partials 420 440 +20
Continue to review full report at Codecov.
|
@ethanfrey this approach is a bit radical, I tried to reuse as many errors as possible from the common package and I think it looks ok, especially considering that blog is not something you necessarily need to do using weave. Let's see what you think |
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.
Generally nice.
Wondering about need of ErrExists
, rather than ErrDuplicate
, which is why not approved.
Curious about benefits of not inlining the Printf strings... please just make a good argument why not (which can go in the best practices readme)
errors/errors.go
Outdated
// ErrInvalidInput stands for general input problems indication | ||
ErrInvalidInput = Register(14, "invalid input") | ||
|
||
// ErrExists already exists error |
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.
What is the distinction between ErrExists and ErrDuplicate?
I guess they could be merged
examples/tutorial/x/blog/handlers.go
Outdated
@@ -90,7 +90,7 @@ func (h CreateBlogMsgHandler) validate(ctx weave.Context, db weave.KVStore, tx w | |||
// Retrieve tx main signer in this context | |||
sender := x.MainSigner(ctx, h.auth) | |||
if sender == nil { | |||
return nil, ErrUnauthorisedBlogAuthor(nil) | |||
return nil, errors.ErrUnauthorized.Newf(unauthorisedBlogAuthor, nil) |
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.
This is odd to me, to see a Printf type function, but not the string, so I don't even know if the next arguments are correct. Can you inline these definitions that use Newf.
For those using New, it is your call to inline or keep them in vars.
examples/tutorial/x/blog/errors.go
Outdated
errBlogNotFound = fmt.Errorf("No blog found for post") | ||
errBlogExist = fmt.Errorf("Blog already exists") | ||
errBlogOneAuthorLeft = fmt.Errorf("Unable to remove last blog author") | ||
invalidTitle = "title is too long or too short" |
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.
These can all be const
, right?
@@ -198,7 +198,7 @@ func (h CreatePostMsgHandler) validate(ctx weave.Context, db weave.KVStore, tx w | |||
return nil, nil, err | |||
} | |||
if obj == nil || (obj != nil && obj.Value() == nil) { | |||
return nil, nil, ErrBlogNotFound() | |||
return nil, nil, errors.ErrNotFound.New("blog") |
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.
👍 nice reuse
examples/tutorial/x/blog/handlers.go
Outdated
} | ||
|
||
// Get the author index | ||
authorIdx := findAuthor(blog.Authors, changeBlogAuthorsMsg.Author) | ||
if changeBlogAuthorsMsg.Add { | ||
// When removing an author we must ensure it does not exist already | ||
if authorIdx >= 0 { | ||
return nil, nil, ErrAuthorAlreadyExist(changeBlogAuthorsMsg.Author) | ||
return nil, nil, errors.ErrExists.Newf("author: %X", changeBlogAuthorsMsg.Author) |
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.
This could be a duplicate error, right?
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.
yes, let's use this. I was looking for exists error and duplicate didn't come up for some reason.
examples/tutorial/x/blog/handlers.go
Outdated
} | ||
|
||
blog := obj.Value().(*Blog) | ||
// Check main signer is one of the blog authors | ||
if findAuthor(blog.Authors, sender.Address()) == -1 { | ||
return nil, nil, ErrUnauthorisedBlogAuthor(sender.Address()) | ||
return nil, nil, errors.ErrUnauthorized.Newf(unauthorisedBlogAuthor, sender.Address()) |
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.
Okay, I have now seen around 4 uses of unauthorizedBlogAuthor
, and see why you extracted it.
Easier to change, but harder to read.
I dunna, ambivilent around it
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.
I reuse format strings for a reason, mainly when there are too many occurrences.
What I will do is rename it to blahBlahFormat
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.
Great job. Made a few comments to polish it, then ready to merge.
Can you do one more pass then ping me so. I can approve?
{errors.New("nonce", errors.CodeUnauthorized), "nonce", errors.CodeUnauthorized}, | ||
{errors.WithCode(fmt.Errorf("no sender"), errors.CodeUnrecognizedAddress), "no sender", errors.CodeUnrecognizedAddress}, | ||
{errors.ErrDecoding(), errors.ErrDecoding().Error(), errors.CodeTxParseError}, | ||
{errors.NormalizePanic("stdlib"), "internal", errors.ErrInternal.ABCICode()}, |
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.
Yes, smaller set of options to create them
} | ||
|
||
// Deliver always returns ErrNoSuchPath | ||
func (h noSuchPathHandler) Deliver(ctx weave.Context, store weave.KVStore, | ||
tx weave.Tx) (weave.DeliverResult, error) { | ||
|
||
return weave.DeliverResult{}, ErrNoSuchPath(h.path) | ||
return weave.DeliverResult{}, errors.ErrNotFound.Newf("path: %s", h.path) |
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.
I like how these are rewritten. Standard error class, with some useful text.
👍
@@ -111,7 +111,7 @@ func (s *StoreApp) parseAppState(data []byte, chainID string, init weave.Initial | |||
var appState weave.Options | |||
err := json.Unmarshal(data, &appState) | |||
if err != nil { | |||
return errors.WithCode(err, errors.CodeTxParseError) | |||
return errors.ErrInternal.New(err.Error()) |
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.
I would prefer
errors.Wrap(err, "json decoding")
It will get internal error code automatically, and seems simpler if we just want to return the raw error with ErrInternal
cmd/bnsd/x/nft/username/handler.go
Outdated
@@ -177,10 +177,10 @@ func (h RemoveChainAddressHandler) Deliver(ctx weave.Context, store weave.KVStor | |||
|
|||
actor := nft.FindActor(h.auth, ctx, t, nft.UpdateDetails) | |||
if actor == nil { | |||
return res, errors.ErrUnauthorizedLegacy() | |||
return res, errors.ErrUnauthorized |
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.
I would like a .New() on here just to capture a stack trace.
But I can do that as part of my pr
@@ -81,11 +81,11 @@ func (t *TokenDetails) Clone() *TokenDetails { | |||
|
|||
func (t *TokenDetails) Validate() error { | |||
if t == nil { | |||
return errors.ErrInternalLegacy("must not be nil") | |||
return errors.ErrInternal.New("must not be nil") | |||
} |
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.
Token details must not be nil
) | ||
|
||
// ABCI Response Codes | ||
// Base SDK reserves 0 ~ 99. |
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.
Delete looks good.
I was wondering if we just remove the entire main.go and common.go files, leaving just errors.go with the new code.
And move anything we need to errors.go to ensure all legacy code is gone
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.
@ethanfrey I'd like to do this in separate iteration so as not to disturb your stack trace PR.
@@ -0,0 +1,17 @@ | |||
/** | |||
Package errors implements custom error interfaces for weave. | |||
|
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.
Good start.
It would be nice to mention the importance of the abci error codes, as they are trasnmitted to the app and the only machine parse able response on an error
x/batch/msg.go
Outdated
@@ -23,7 +23,7 @@ func Validate(msg Msg) error { | |||
} | |||
|
|||
if len(l) > MaxBatchMessages { | |||
return errors.ErrTooLarge() | |||
return errors.ErrInvalidInput.New("transaction is too large") |
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.
Can you add the number of message and the maximum limit here? This makes it easier to correct client side
x/namecoin/handler.go
Outdated
@@ -170,7 +170,7 @@ func (h SetNameHandler) Deliver(ctx weave.Context, db weave.KVStore, | |||
return res, err | |||
} | |||
if obj == nil { | |||
return res, ErrNoSuchWallet(msg.Address) | |||
return res, errors.ErrNotFound.Newf("wallet %X", msg.Address) |
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.
Careful to use %X with weave.Address....
Since address.String will output as hex, using %X will hex encode the hex output and create confusion.
I just caught this one case, but please check the use of Address variables elsewhere also
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.
@ethanfrey this is the same behavior we had before refactor. I can use string %s if that's easier.
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.
actually, this is used all over the place in our code. I will change address usages to %s
@ethanfrey should be all done 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.
Good fixes
fixes #309
fixes #333