Formalize and document an "error variable convention" that sufficiently removes ambiguity around:
When it is appropriate to define a new error variable / determine any existing errors are not applicable
Naming error variables such that they are unique and representative of their intended usage
Scoping the error variables message to avoid being overly specific, and therefore non-applicable in all conventionally intended use cases
Origin Document
We seem to have a few degrees of freedom with respect to our "error variable convention" and I'm concerned that we're not using or thinking about them consistently across the team (and/or perhaps even, individually, over time :sweat_smile:).
IIRC we initially carved out a convention to the effect of:
Error variables MUST:
Begin with Err<owning module name>
Where <owning module name> would match the module directory in which the error is defined and primarily used.
Be defined in an x/<module name>/types/error.go file (according to 1.).
However it seems to me that the conventional intended usage scope of the error message itself has yet to be bounded, and in some cases (see the example below) has been made too specific for the error to be generally applicable. This leads to two possible outcomes (each time):
The error is made more general and the specific aspects are pushed "down" into the message/format string that is passed to #Wrap()/#Wrapf(). This may also potentially require/involve renaming the error to match the more general level of specificity.
A new error is added to the same module error set (likely with similar specificity) to apply in the new case.
I would argue that we should prefer 1. over 2. and that this should be formally captured in an "error variable convention" document that extends the existing considerations (above).
Additionally, the lack of a more complete convention leaves an open question around when it is and is not appropriate to use errors from a different module.
E.g. In a scenario where an application address is "invalid" in some supplier module business logic, should we use app.ErrAppInvalidAddress or supplier.ErrSupplierInvalidAddress](https://github.com/pokt-network/poktroll/blob/main/x/supplier/types/errors.go#L12)). The confusion comes from the fact that (currently) ErrAppInvalidAddress's message is more specific: "invalid application address", whereas ErrSupplierAddress is more general: "invalid address". In the later case, it seems like the expectation is that the specifics of which actor's address is invalid is to be included in the message passed to #Wrap().
Goals
Improve readability and maintainability of error variables and their usages by ensuring consistency around the aspects outlined in the objective above.
Ensure consistency around error test assertions.
Determine whether to use sdkerrors/errorsmod errors in off-chain code.
Deliverables
[ ] identify how many different contexts there are in error management and if it should differ:
On-chain (cosmos best practices?)
Off-chain (anything different?)
Observable (anything unique?)
Etc..
[ ] Present a list of ideas / alternatives (as explained above) to the core protocol team and get alignment on next steps
[ ] Create a docusaurus or notion document that will be the source of truth for the "error variable convention".
[ ] A PR (or multiple) that refactors any existing and non-compliant errors, usages, and test assertions to conform to the convention. Search each module for functions that return an error or panic.
Non-goals / Non-deliverables
Updating unrelated error-handling logic
Updating infra to aggregate errors or get visibility into them (cc @okdas for future work)
General deliverables
[ ] Comments: Add/update TODOs and comments alongside the source code so it is easier to follow.
[ ] Testing: Add new tests (unit and/or E2E) to the test suite.
[ ] Makefile: Add new targets to the Makefile to make the new functionality easier to use.
[ ] Documentation: Update architectural or development READMEs; use mermaid diagrams where appropriate.
Objective
Formalize and document an "error variable convention" that sufficiently removes ambiguity around:
Origin Document
We seem to have a few degrees of freedom with respect to our "error variable convention" and I'm concerned that we're not using or thinking about them consistently across the team (and/or perhaps even, individually, over time :sweat_smile:).
IIRC we initially carved out a convention to the effect of:
However it seems to me that the conventional intended usage scope of the error message itself has yet to be bounded, and in some cases (see the example below) has been made too specific for the error to be generally applicable. This leads to two possible outcomes (each time):
#Wrap()
/#Wrapf()
. This may also potentially require/involve renaming the error to match the more general level of specificity.I would argue that we should prefer 1. over 2. and that this should be formally captured in an "error variable convention" document that extends the existing considerations (above).
Additionally, the lack of a more complete convention leaves an open question around when it is and is not appropriate to use errors from a different module.
E.g. In a scenario where an application address is "invalid" in some supplier module business logic, should we use
app.ErrAppInvalidAddress
orsupplier.ErrSupplierInvalidAddress
](https://github.com/pokt-network/poktroll/blob/main/x/supplier/types/errors.go#L12)). The confusion comes from the fact that (currently)ErrAppInvalidAddress
's message is more specific:"invalid application address"
, whereasErrSupplierAddress
is more general:"invalid address"
. In the later case, it seems like the expectation is that the specifics of which actor's address is invalid is to be included in the message passed to#Wrap()
.Goals
sdkerrors
/errorsmod
errors in off-chain code.Deliverables
Non-goals / Non-deliverables
General deliverables
Creator: @bryanchriswhite Co-Owners: ❓