-
Notifications
You must be signed in to change notification settings - Fork 140
Add docs on clever errors #99
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
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,230 @@ | ||||||
| # Clever Errors | ||||||
|
|
||||||
| Clever errors are a feature that allows for more informative error messages when an assertion fails | ||||||
| or an abort is raised. They are a source feature and compile to a `u64` abort code value that | ||||||
| contains the information needed to access the line number, constant name, and constant value given | ||||||
| the clever error code and the module that the clever error constant was declared in. Because of | ||||||
| this, post-processing is required to go from the `u64` abort code value to a human-readable error | ||||||
| message. This post-processing is automatically performed by the Sui GraphQL server, as well as the | ||||||
tzakian marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||
| Sui CLI. If you want to manually decode a clever abort code, you can use the process outlined in | ||||||
| [Inflating Clever Abort Codes](#inflating-clever-abort-codes) to do so. | ||||||
|
|
||||||
| > Clever errors include source line information amongst other data. Because of this their value may | ||||||
| > change due to any changes in the source file (e.g., due to auto-formatting, adding a new module | ||||||
| > member, or adding a newline). | ||||||
|
|
||||||
| ## Clever Abort Codes | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you add a link to a matching page in the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don't have one in the |
||||||
|
|
||||||
| Clever abort codes allow you to use non-u64 constants as abort codes as long as the constants are | ||||||
| annotated with the `#[error]` attribute. They can be used both in assertions, and as codes to | ||||||
| `abort`. | ||||||
|
|
||||||
| ```move | ||||||
| module 0x42::a_module; | ||||||
|
|
||||||
| #[error] | ||||||
| const EIsThree: vector<u8> = b"The value is three"; | ||||||
|
|
||||||
| // Will abort with `EIsThree` if `x` is 3 | ||||||
| public fun double_except_three(x: u64): u64 { | ||||||
| assert!(x != 3, EIsThree); | ||||||
| x * x | ||||||
| } | ||||||
|
|
||||||
| // Will always abort with `EIsThree` | ||||||
| public fun clever_abort() { | ||||||
| abort EIsThree | ||||||
| } | ||||||
| ``` | ||||||
|
|
||||||
| In this example, the `EIsThree` constant is a `vector<u8>`, which is not a `u64`. However, the | ||||||
| `#[error]` attribute allows the constant to be used as an abort code, and will at runtime produce a | ||||||
| `u64` abort code value that holds: | ||||||
|
|
||||||
| 1. A set tag-bit that indicates that the abort code is a clever abort code. | ||||||
| 2. The line number of where the abort occured in the source file (e.g., 7). | ||||||
| 3. The index in the module's identifier table for the constant's name (e.g., `EIsThree`). | ||||||
| 4. The index of the constant's value in the module's constant table (e.g., `b"The value is three"`). | ||||||
|
|
||||||
| In hex, if `double_except_three(3)` is called, it will abort with a `u64` abort code as follows: | ||||||
|
|
||||||
| ``` | ||||||
| 0x8000_7000_1000_0000 | ||||||
tzakian marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||
| ^ ^ ^ ^ | ||||||
| | | | | | ||||||
| | | | | | ||||||
| | | | +-- Constant value index = 0 (b"The value is three") | ||||||
| | | +-- Constant name index = 1 (EIsThree) | ||||||
| | +-- Line number = 7 (line of the assertion) | ||||||
| +-- Tag bit = 0b1000_0000_0000_0000 | ||||||
| ``` | ||||||
|
|
||||||
| And could be rendered as a human-readable error message as (e.g.) | ||||||
|
|
||||||
| ``` | ||||||
| Error from '0x42::a_module::double_except_three' (line 7), abort 'EIsThree': "The value is three" | ||||||
| ``` | ||||||
|
|
||||||
| The exact formatting of this message may vary depending on the tooling used to decode the clever | ||||||
| error however all of the information needed to generate a human-readable error message like the | ||||||
| above is present in the `u64` abort code when coupled with the module where the error occurred. | ||||||
|
|
||||||
| > Clever abort code values do _not_ need to be a `vector<u8>` -- it can be any valid constant type | ||||||
| > in Move. | ||||||
|
|
||||||
| ## Assertions with no Abort Codes | ||||||
|
|
||||||
| Assertions, and `abort` statements without an abort code will automatically derive an abort code | ||||||
|
||||||
| Assertions, and `abort` statements without an abort code will automatically derive an abort code | |
| Assertions and `abort` statements without an abort code will automatically derive an abort code |
tzakian marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
tzakian marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
Outdated
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.
get_identifier_at_table_index
I appreciate this is pseudo code, but do we have a method for this?
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.
We do, but its name is not quite as descriptive as I would like here (identifier_at). I'll try and make it a bit closer, but I think having a more descriptive name here will be beneficial.
Uh oh!
There was an error while loading. Please reload this page.