Skip to content

Improve Handler interface #4844

Closed
Closed
@ethanfrey

Description

Summary

With #4821, I provided a nice error library with stacktrace support for cosmos-sdk. This addressed #4708 to allow developers to get stack traces on test failures, if they use the new errors.

However, once we hit the Handler interface, we can no longer use the error interface, but rather fit it into a sdk.Result: type Handler func(ctx Context, msg Msg) Result. This encourages many functions to return sdk.Error, then return err.Result() at the Handler interface. Which discourages use of richer error structs.

Problem Definition

Passing a consistent, stacktrace-enriched error class allows much better test-ability at all layers, especially at Handler-level or app-level integration tests. Let's make these errors first class citizens.

I have discussed this with @marbar3778 and he liked these changes. I would like to get more opinion from the other devs. I am happy for feedback here early on, and if you like the goal, but want a smoother migration path, I can provide a proposal for backwards compatibility here as well.

Proposal

I propose a few steps, some breaking, some non-breaking.

  1. Add sdk.ResultFromError(err error). If err implements sdk.Error, then we call the Result method on it. If not, then we call types/errors.ABCIInfo() to get the info and generate an sdk.Result from that. We can standardize on this usage, and allow an incremental migration from existing error package

  2. Change type Handler func(ctx Context, msg Msg) Result to type Handler func(ctx Context, msg Msg) (*Result, error). And remove Code and Codespace from Result. Result should only be returned on success, error on failure. runTx/runMsg in BaseApp can construct an ABCIResult properly on success or failure. In practice, this may be done in multiple steps to be less breaking, but should be after v0.36 in any case. (Note that we can still use sdk.Error and just return it without .Result() as a first step, only changing the error creation piece by piece through the modules that desire it)

Advantages:

  • Pass go error interface not ABCI-like Result struct to allow stacktrace info to flow over all levels of the code
  • Allow go-standard error checking rather than sdk-specific code
  • Encourage go-standard extensions using (*Result error) design rather than returning sdk.Result or sdk.Error down into the Keeper and below.

Current:

res := h.keeper.DoStuff()
if !res.IsOK() {
  return res
}

Proposed:

res, err := h.keeper.DoStuff()
if err != nil {
  return nil, err
}

For Admin Use

  • Not duplicate issue
  • Appropriate labels applied
  • Appropriate contributors tagged
  • Contributor assigned/self-assigned

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions