-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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: API: support typed errors over RPC #9061
Conversation
Codecov Report
Additional details and impacted files@@ Coverage Diff @@
## release/v1.18.0 #9061 +/- ##
==================================================
Coverage ? 41.02%
==================================================
Files ? 708
Lines ? 78898
Branches ? 0
==================================================
Hits ? 32365
Misses ? 41014
Partials ? 5519 |
We could make go-jsonrpc recursively errors.Unwrap the error until it hits a registered error (with some depth limit just in case), then have it return a "wrapped" version of that error:
|
9f475ba
to
af56893
Compare
10e6284
to
f7ddb86
Compare
cmd/lotus/daemon.go
Outdated
"github.com/filecoin-project/lotus/api" | ||
lapi "github.com/filecoin-project/lotus/api" |
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.
duplicate import
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.
fixed
Tests seem to be broken because of this really robust error check: https://github.com/filecoin-project/lotus/blob/master/itests/kit/blockminer.go#L194 (which we can now make actually robust with this PR) |
cb62e53
to
6c23b7b
Compare
5e91725
to
8022543
Compare
8022543
to
0626286
Compare
lib/retry/retry_test.go
Outdated
func TestRetryErrorIsInTrue(t *testing.T) { | ||
errorsToRetry := []error{&jsonrpc.RPCConnectionError{}} | ||
require.True(t, ErrorIsIn(&jsonrpc.RPCConnectionError{}, errorsToRetry)) | ||
require.True(t, api.ErrorIsIn(&jsonrpc.RPCConnectionError{}, errorsToRetry)) | ||
} | ||
|
||
func TestRetryErrorIsInFalse(t *testing.T) { | ||
errorsToRetry := []error{&jsonrpc.RPCConnectionError{}} | ||
require.False(t, ErrorIsIn(xerrors.Errorf("random error"), errorsToRetry)) | ||
require.False(t, api.ErrorIsIn(xerrors.Errorf("random error"), errorsToRetry)) | ||
} | ||
|
||
func TestRetryWrappedErrorIsInTrue(t *testing.T) { | ||
errorsToRetry := []error{&jsonrpc.RPCConnectionError{}} | ||
require.True(t, ErrorIsIn(xerrors.Errorf("wrapped: %w", &jsonrpc.RPCConnectionError{}), errorsToRetry)) | ||
require.True(t, api.ErrorIsIn(xerrors.Errorf("wrapped: %w", &jsonrpc.RPCConnectionError{}), errorsToRetry)) | ||
} |
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.
Technically those tests should also be moved to api/
itests/kit/blockminer.go
Outdated
@@ -191,7 +192,7 @@ func (bm *BlockMiner) MineBlocksMustPost(ctx context.Context, blocktime time.Dur | |||
reportSuccessFn := func(success bool, epoch abi.ChainEpoch, err error) { | |||
// if api shuts down before mining, we may get an error which we should probably just ignore | |||
// (fixing it will require rewriting most of the mining loop) | |||
if err != nil && !strings.Contains(err.Error(), "websocket connection closed") { | |||
if err != nil && !strings.Contains(err.Error(), "websocket connection closed") && !api.ErrorIsIn(err, []error{&jsonrpc.RPCConnectionError{}}) { |
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.
supernit:
if err != nil && !strings.Contains(err.Error(), "websocket connection closed") && !api.ErrorIsIn(err, []error{&jsonrpc.RPCConnectionError{}}) { | |
if err != nil && !strings.Contains(err.Error(), "websocket connection closed") && !api.ErrorIsIn(err, []error{new(jsonrpc.RPCConnectionError)}) { |
Another use case where this would be helpful: |
7479cc8
to
3e81c56
Compare
Backport: #9061 rpc errors
@magik6k sorry for these questions after the code merge Recently venus intended to submit some of venus changes and bug fixes for rpc to the upstream, but when pushing it, it found many conflicts with TypeError In PR, I think the current implementation of TypeError is a bit complicated. I'm not sure if users really need the MarshalJson/UnMarshalJson functionality, but I'm looking at lotus/boost usage and it's enough to determine the type of error, and in venus requirements it's enough to determine the type of error. ErrorCode is a good idea, but maybe more better to define ErrorCode as true error type like below code type ErrorCode int
func (e ErrorCode) Error() string {
return fmt.Sprintf("error code %d", e)
} for rpc server , user fmt.Error to return specific error if res.MsgRct.ExitCode == exitcode.SysErrOutOfGas {
return -1, rpc.ErrorCode(exitcode.SysErrOutOfGas)
} or convert all exitcode to rpc error if res.MsgRct.ExitCode != exitcode.Ok {
return -1, xerrors.Errorf("message execution failed: exit %w, reason: %s", rpc.ErrorCode(res.MsgRct.ExitCode), res.Error)
} for rpc client, use this code to check error type require.True(t, xerrors.Is(err, rpc.EOutOfGas)) If write it this way, not need to add the Register function in Rpc, and the Rpc implementation can be simpler without adding the meta field in Respnse. |
Related Issues
This is work towards, but does not finish #9041
Proposed Changes
Additional Info
Checklist
Before you mark the PR ready for review, please make sure that:
<PR type>: <area>: <change being made>
fix: mempool: Introduce a cache for valid signatures
PR type
: fix, feat, INTERFACE BREAKING CHANGE, CONSENSUS BREAKING, build, chore, ci, docs,perf, refactor, revert, style, testarea
: api, chain, state, vm, data transfer, market, mempool, message, block production, multisig, networking, paychan, proving, sealing, wallet, deps