如何检测 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.js 中正确使用还原原因在 UI 中显示有意义的错误消息