1

While calling a read only method on my ink contract, I get an error that looks like following enter image description here

On my contract, I have a check to throw an error like:

if paid <= MIN_VESTING_AMOUNT{
    return  Err(Error::VestingAmountTooLow);
}

However the error message that I have received on the client side doesn't exactly tell me what went wrong in the call. Instead it just gives a generic message ContractTrapped on every error on the contract.

Is there a way to decode the actual error message?

5
  • if the contract return Err(Error::VestingAmountTooLow), does it still say CalleTrapped?
    – kriko.eth
    Commented Jan 5, 2023 at 10:12
  • Yep. It still says the same error for every error that I throw on the contract
    – Non-named
    Commented Jan 5, 2023 at 10:59
  • I guess your error doesn't come from your contract but rather from the runtime (mostly pallet-contract). What you can do is get the tx hash of your transaction and in polkadot js UI developer > RPC calls > contracts - call dry-run it to get the proper Error enum variant
    – P.Ossun
    Commented Jan 6, 2023 at 8:57
  • BTW I am assuming you are calling a read-only function as query (but the question title said otherwise). If you process as a tx you can do like this: Best practise
    – P.Ossun
    Commented Jan 6, 2023 at 9:01
  • good point, if you do not return Err, do you get such error too?
    – kriko.eth
    Commented Jan 7, 2023 at 15:01

2 Answers 2

1

You can query the contract method before creating a transaction as it will return any possible error that can occur during the contract call. This will also save the gas fee of the callee since the query will not deduce any gas fee

        const res = await contractPromise.query[queryFunc](accountId, { gasLimit: -1, storageDepositLimit: null}, ...args);
        const { output, result} = res;

        if (output?.isErr || result?.isErr) {
            const errorMsg = output?.toJSON()?.err || result?.toJSON()?.err;
            throw new Error(errorMsg || 'occurred due to unknown reason');
        }

Note1: Please replace "queryFunc" with contract method name.

Note2: you can get information about contract query from this link.

1

Your error is coming from one of the pallets. You can tell that since it has Module which is an enum from DispatchError.

Module {
    index: 20,
    error: 0x0b
}
  • Index 20 is pointing to the concerned pallet on the node you are using. Go to runtime/src/lib.rs of the node you are using to find construct_runtime! macro and check which pallet has index 20. It can be assigned number or just count pallets until you come to pallet on position 20. Start counting with 0.

  • To find error 0x0b, you need to go to the lib.rs of the pallet (with index 20) and again find the error on position 11 (0xb). Start with index=0.

However if this error is from pallet-contracts the easiest way to find the error is from your unit test like this:

let r = contract.my_function();
println!("result {:?}", r);

or wrap it in assert!

assert_eq!(contract.my_function(), expected_result);

Using polkadot.js to debug your contract is not very helpful.

2
  • Thanks for the answer, but that still doesn't provide the exact error message thrown from the contract to the client side
    – Non-named
    Commented Jan 6, 2023 at 7:03
  • can you post what you get as println! result? Error will be number if you made errors es enum
    – Maario
    Commented Jan 6, 2023 at 9:14

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.