In my contract, I have a requirement to call messages from external contracts without knowing their specific identities beforehand. To achieve this, I utilize the call builder, enabling the execution of transactions at a low level. Since these transactions may encounter failures, I adopt the try_invoke
method, which facilitates error handling. The try_invoke
method can return two types of errors:
- Errors arising from the underlying execution environment (
ink::env::Error
). - Errors stemming from the programming language itself (
ink::LangError
).
Below is the section of code where I implement this functionality:
...
// Fetch the transaction
let tx = self.get_tx(tx_id).expect("This should never fail because we are checking the tx_id before calling this function");
let tx_result = build_call::<<Self as ::ink::env::ContractEnv>::Env>()
.call(tx.address)
.gas_limit(tx.gas_limit)
.transferred_value(tx.transferred_value)
.call_flags(CallFlags::default().set_allow_reentry(tx.allow_reentry))
.exec_input(ExecutionInput::new(tx.selector.into()).push_arg(InputArgs(&tx.input)))
.returns::<Vec<u8>>()
.try_invoke();
// Instead of just returning a custom Error we could return the error from the call
let result = match tx_result {
Ok(Ok(bytes)) => TxResult::Success(bytes),
Ok(Err(e)) => TxResult::Failed(Error::LangExecutionFailed(e)),
Err(e) => TxResult::Failed(Error::EnvExecutionFailed(e)), // Here is where i need to wrap the error in order to provide useful information about the tx failure
};
...
I defined two custom errors that serve as wrappers for the errors thrown by the try_invoke
method.
#[derive(scale::Encode, scale::Decode)]
#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))]
pub enum Error {
/// Env error encountered when executing the transaction
EnvExecutionFailed(ink::env::Error),
/// Transaction executed but Lang error encountered
LangExecutionFailed(ink::LangError),
...
}
However, during compilation, I encountered the following errors:
The trait WrapperTypeEncode is not implemented for ink::ink_env::Error.
The trait WrapperTypeDecode is not implemented for ink::ink_env::Error.
I've come to understand that the error is being thrown because ink::env::Error
does not implement scale::Encode
and scale::Decode
traits. I'm wondering if there's a way to manually implement these traits, or if there is another solution.