Call response
You've probably noticed that you're often chaining .call().await.unwrap(). That's because:
- You have to choose between
.call()and.simulate()(more on this in the next section). - Contract calls are asynchronous, so you can choose to either
.awaitit or perform concurrent tasks, making full use of Rust's async. .unwrap()theResult<CallResponse, Error>returned by the contract call.
Once you unwrap the CallResponse, you have access to this struct:
pub struct CallResponse<D> {
pub value: D,
pub receipts: Vec<Receipt>,
pub gas_used: u64,
pub log_decoder: LogDecoder,
pub tx_id: Option<Bytes32>,
}
Where value will hold the value returned by its respective contract method, represented by the exact type returned by the FuelVM, E.g., if your contract returns a FuelVM's u64, value's D will be a u64. If it's a FuelVM's tuple (u8,bool), then D will be a (u8,bool). If it's a custom type, for instance, a Sway struct MyStruct containing two components, a u64, and a b256, D will be a struct generated at compile-time, called MyStruct with u64 and a [u8; 32] (the equivalent of b256 in Rust).
receiptswill hold all receipts generated by that specific contract call.gas_usedis the amount of gas it consumed by the contract call.tx_idwill hold the ID of the corresponding submitted transaction.
Error handling
You can use the is_ok and is_err methods to check if a contract call Result is Ok or contains an error. These methods will return either true or false.
let is_ok = response.is_ok();
let is_error = response.is_err();
If is_err returns true, you can use the unwrap_err method to unwrap the error message.
if response.is_err() {
let err = response.unwrap_err();
println!("ERROR: {:?}", err);
};