1

I have a getter function in my smart contract that returns one of the string values in statically defined string array. Upon entry to the function, it does a bounds check on the incoming index using require(). If the bounds check fails, what will happen in my Node.JS app that used Web3.js to make the call? Will a Javascript error be thrown? Will I get NULL back?

If anyone has a good article or web resource that shows the proper way to handle errors from a Web3.JS call that resulted in an assert or require operation being triggered on the smart contract side, please share.

Here is my smart contract code:

pragma solidity ^0.4.23;

import "github.com/OpenZeppelin/zeppelin-solidity/contracts/ownership/Ownable.sol";

contract VideoDummyData is Ownable{

    // Constructor, MUST be public.
    constructor() public {
        // Unused.
    }

    // Array of sample video IDs.
    string[3] m_aryVideoIds = 
        ["ZUSPD9zOyJs", "4nqJiBRNQuw", "PLcxE4UkJt0"];


    // Return one of the sample video IDs.
    function getVideoIdAt (uint ndx) public view returns(string)
    {
        // Bounds check on the desired index.
        require(ndx < m_aryVideoIds.length);

        return m_aryVideoIds[ndx];
    }
}
4
  • 1
    You will just get an error from web3, but you won't be able to know what is the exact error. Commented May 4, 2018 at 8:58
  • @Andromelus - not until the next version of solidity right, when they being to allow you to return an error message with assert/revert? If I am right about that, do you know if the change will be immediate, or will we need to wait for all the nodes on the Ethereum network to update or adopt the change (like a soft fork)? Commented May 4, 2018 at 11:07
  • 1
    You only need the transaction to be mined. So the node you are connected to needs to know the block in which one the tx is inside. Commented May 5, 2018 at 7:04
  • This is about a call to a view function so there is no transaction to be mined. Commented Oct 26, 2018 at 22:38

2 Answers 2

0

Since you are calling a view function, the first callback will error, more or less immediately.

It's currently possible to return errors with

require(expression, "error msg");

The challenge is accessing this message further up the stack in Web3 and Node.

In the meantime, you can use try and .catch() in promisified code such as a truffle contract abstraction.

You won't know the exact reason but you'll be able to infer it given the contract's requirements.

Hope it helps.

0

Once you call/send methods get reverted with what so ever reason you be getting the below response in you express/nodejs code.

   {
    "data": {
        "0x926192b712005c4eab709b7f7e1718435b6f2117580360b73e7601a439feffcd": {
            "error": "revert",
            "program_counter": 383,
            "return": "0x08c379a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000165468697320496420616c72656164792065786973747300000000000000000000",
            "reason": "This Id already exists"
        },
        "stack": "RuntimeError: VM Exception while processing transaction: revert This Id already exists\n    at Function.RuntimeError.fromResults (C:\\Program Files\\WindowsApps\\GanacheUI_2.5.4.0_x64__5dg5pnz03psnj\\app\\resources\\static\\node\\node_modules\\ganache-core\\lib\\utils\\runtimeerror.js:94:13)\n    at BlockchainDouble.processBlock (C:\\Program Files\\WindowsApps\\GanacheUI_2.5.4.0_x64__5dg5pnz03psnj\\app\\resources\\static\\node\\node_modules\\ganache-core\\lib\\blockchain_double.js:627:24)\n    at processTicksAndRejections (internal/process/task_queues.js:93:5)",
        "name": "RuntimeError"
    }
}

Now here we need to show the user a appropriate message so the user can understand for that we can use below code. To get the reason from the reverted response. use the below code in nodeJS/expressjs code....

try {
    await myContract.methods.foo().send();
} catch (e) {
    const data = e.data;
    const txHash = Object.keys(data)[0]; 
    const reason = data[txHash].reason;

    console.log(reason); 
}

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.