如何检测 web3.js 中的错误

Posted

技术标签:

【中文标题】如何检测 web3.js 中的错误【英文标题】:how to detect errors in web3.js 【发布时间】:2021-09-22 07:56:39 【问题描述】:

这是我的代码

for(var i = 0 ; i <= 4 ; i++)
myContract.methods.contractmanager(i).call().then((res)=>
console.log(res[0]);
):

我的合同中存储了 2 个数据,我想打印它,但它并不总是 2 个,它会更加动态,我不知道它们会有多少。执行此代码后,我有 2 个输出和 2 个错误。如何使循环在 2 处停止并且不会显示错误?如何检测错误并打破循环?如何判断输出是否为空? 可靠性代码:

function contractmanager(uint i) public view returns(uint , address , address , uint , uint , uint)
            return (contrs[list_contr[i]].idc , contrs[list_contr[i]].seller , contrs[list_contr[i]].buyer, contrs[list_contr[i]].price ,contrs[list_contr[i]].date , contrs[list_contr[i]].pos );
    

【问题讨论】:

请编辑您的问题并分享contractmanager() Solidity 函数及其依赖项。这将使我们能够更好地解决您的问题。 完成。但它并不重要。它只是返回数据 list_contr[i]contrs[list_contr[i]] 存在吗?它们的数据类型是什么(例如,动态长度数组、映射……)? ...您是否有可能尝试访问数组的未定义项? (示例:数组的长度为 2,但您尝试获取索引 3。) 它是一个动态数组,我想在 javascript 中获取数据,所以我需要一个 for 循环来获取数据。例如它的长度是 5 但我的 for 循环一直持续到 50 我想打印 5 个数据数组并检测到该数组为空 【参考方案1】:

当您尝试访问索引高于数组长度的数组项时,EVM 会引发异常。和其他语言的“数组索引越界”异常基本一样。

您需要创建一个单独的函数来获取数组长度(请参阅下面示例中的myArrayLength())并以这种方式在您的 JS 代码中执行长度检查。


示例:

团结

pragma solidity ^0.8;

contract MyContract 
    uint256[] public myArray;
    
    function addToArray(uint256 _value) external 
        myArray.push(_value);
    
    
    function myArrayLength() external view returns (uint256) 
        return myArray.length;
    

Node.js

const Web3 = require('web3');

const WEB3_PROVIDER = 'http://127.0.0.1:7545/';
const ABI_JSON = [
    "inputs": ["internalType": "uint256", "name": "_value", "type": "uint256"],
    "name": "addToArray",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
, 
    "inputs": ["internalType": "uint256", "name": "", "type": "uint256"],
    "name": "myArray",
    "outputs": ["internalType": "uint256", "name": "", "type": "uint256"],
    "stateMutability": "view",
    "type": "function"
, 
    "inputs": [],
    "name": "myArrayLength",
    "outputs": ["internalType": "uint256", "name": "", "type": "uint256"],
    "stateMutability": "view",
    "type": "function"
];
const CONTRACT_ADDRESS = '0xCc0607EfdF166344fc94589a61F09dcFbC89B1a7';
const FROM_ADDRESS = '0x8553DA9C81f940041ee4F46c14e2C7b20ad32F8C';

const run = async () => 
    const web3 = new Web3(WEB3_PROVIDER);
    const contract = new web3.eth.Contract(ABI_JSON, CONTRACT_ADDRESS);

    await contract.methods.addToArray(123).send(from: FROM_ADDRESS); // sets the first item

    const firstItem = await contract.methods.myArray(0).call(); // retrieves the item with index 0 (the existing, first item)
    console.log(firstItem);

    try 
        const otherItem = await contract.methods.myArray(100).call(); // tries to retrieve the item with index 100 (non-existing)
     catch (e) 
        console.log("Failed");
    

    const length = await contract.methods.myArrayLength().call();
    console.log(length);


run();

控制台输出

123
Failed
1

【讨论】:

感谢您的回答,但这是我的主要问题:“catch”没有收到错误,也没有在控制台中打印“失败”消息,它只是记录错误 我也有同样的问题,如果调用的合约方法出错(比如 require()),catch 不会被触发【参考方案2】:

您可以使用如下代码中的“.catch()”方法:

async function getBlockInfo(i) 
    await web3.eth.getBlock(i).then(block => 
        block.transactions.forEach(function (t) 
            web3.eth.getTransaction(t).then(transaction => 
                console.log(i + ' ' + transaction.hash + ' ' + transaction.from + ' ' + transaction.to)
            ).catch((error) => 
                console.log('erreur')
            )
        )
    ).catch((error) => console.log(error))

【讨论】:

以上是关于如何检测 web3.js 中的错误的主要内容,如果未能解决你的问题,请参考以下文章

在 web3.py 中检测还原的事务

如何在 web3.js 中正确使用还原原因在 UI 中显示有意义的错误消息

javascript web3.js 库错误

如何使用 @solana/web3.js 从 Solana 中的自定义令牌中删除铸币权限?

如何使用 web3.js 注销 MetaMask 帐户

部署智能合约时出现节点错误 - Web3.js