-
Notifications
You must be signed in to change notification settings - Fork 249
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
Standardize errors #1165
base: master
Are you sure you want to change the base?
Standardize errors #1165
Conversation
…handlesresultwithstatus to handlesresultimplicit
to keep the legacy behavior, mark the method with #[handle_result] and make \ | ||
it return Result<Result<T, E>, near_sdk::Abort>.", | ||
)) | ||
Ok(ReturnKind::HandlesResultImplicit(crate::StatusResult { |
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 to mention this change: from some time using Result without #[handle_result] became deprecated. So introducing it again may break contracts that use that old sdk and move to the new version. Please let me know if this change should be reconsidered.
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.
Thanks for flagging it. Could you, please, dig into the git history/blame to learn why it was decided to use an explicit attribute instead of handling Result
types?
This change won't break previously compilable contracts. We only change the behavior for the contracts that could not have been compiled before or very old contracts which we won't migrate to this new SDK anyway.
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.
It was initially called #[return_result]
instead of #[handle_result]
- change applied
Here is the first issue about this macro and comment by austinabell. According to the comment I believe it was decided to use explicit attribute so that it does not accidentally break existing contracts. So the macro was introduced in March 2022 along with forbidding to use Result without macro a bit later.
ci: fix 1.78 lints
…ent state, some others
Closes #936
The following information comes from docs:
Panic behaviour
If return type is
Result<OkType, ErrType>
and, the function is not marked with#[handle_result]
andErrType
struct implementsnear_sdk::ContractErrorTrait
(i.e. used with#[near_sdk::contract_error]
)When the contract call happens:
Result
value isErr
, panic is called and state is not written.As soon as
ErrType
implementsContractErrorTrait
, it is returned as a well-defined structure.If the error struct does not implement
ContractErrorTrait
, the code should not compile.#[persist_on_error]
is used on method, panic is not called.And the contract state is written safely.
But the extra
<method_name>_error
method is generated.And this method is called in a new Promise.
This method effectively panics with structured error.
Example:
contract_error macro
This attribute macro is used on a struct or enum to generate the necessary code for an error
returned from a contract method call.
Example:
For the error:
And the function:
The error is serialized as a JSON object with the following structure:
Note: you can assign any error defined like that to
BaseError
:Use inside_nearsdk attribute (
#[contract_error(inside_nearsdk)]
) if the error struct is defined inside near-sdk.Don't use if it is defined outside.
Internally, it makes error struct to:
near_sdk::ContractErrorTrait
so that it becomes correct errorwhich can be returned from contract method with defined structure.
From<ErrorStruct> for near_sdk::BaseError
as a polymorphic solutionFrom<ErrorStruct> for String
to convert the error to a stringunwrap_on_err macro
Helper macro to unwrap an
Option
orResult
, returning an error ifNone
orErr
.If you have an option you would like to unwrap, you use
unwrap_or_err!
on it andprovide an error that will be returned from the function in case the option value is
None
If you have a result you would like to unwrap, you use
unwrap_or_err!
on it andthe error will be returned from the function in case the result is an
Err
Examples
require_on_err macro
Helper macro to create assertions that will return an error.
This macro can be used similarly to [
require!
] but will return an error instead of panicking.Returns Err(near_sdk::errors::RequireFailed) unless error message provided
Examples
Examples