Skip to main content

contract_exception

Attribute Macro contract_exception 

Source
#[contract_exception]
Expand description

#[contract_exception] or #[contract_exception(version = "1.0.0", name = "...")] — full convenience macro: derives + #[repr(i32)] + impl Exn + impl ContractTypeName.

name = "..." renames the type in the spec as it does for #[contract_type], and may not contain :: either.

wire_crate = "..." pins the package label used in the selector hash. Use it for a protocol-defined exception whose wire identity must survive a package rename. It does not change the type’s spec name or provenance.

§Exception payloads cannot carry auth tokens

No field may be — or contain — a thruput_sdk::signer::Signed.

A Signed occupies zero wire bytes; its real handle arrives out of band in the auth-token list the host returns beside a successful return. Abort frames carry no such list (the host refuses to return auth tokens on a revert frame), so a Signed reached through an exception decodes to the uninitialized u32::MAX sentinel — a value that looks like an auth token, is not one, and faults when consumed or returned.

There is no way to write this correctly, so hand the token back through a successful return instead, or identify it by something inert (the minter’s address, an id) and let the caller re-obtain it.

Two things catch it. This macro’s PartialEq derive (required by Exn) blocks the direct route — Signed does not implement PartialEq — so reaching the situation at all takes hand-written impls (or #[exn]). Beyond that, spec canonicalization walks each throws(...) payload when the contract is built and rejects any that reaches a signed token, however deeply nested, so hand-rolled types do not slip through.