0

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:

  1. Errors arising from the underlying execution environment (ink::env::Error).
  2. 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.

3

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.