Web3js

React 中的 Web3 錯誤處理

  • April 1, 2022

這真的是一個兩部分的問題。

首先,我可以獲得智能合約require語句拋出的錯誤消息的唯一方法是首先使用 acall而不是 a呼叫該函式sendsend不返回失敗require語句引發的消息,而返回call

例子。在 Solidity 中,我可能有以下內容:

require (org._isUser(_user),'Error: User not registered');

在我的 React 前端,我希望能夠顯示“錯誤:使用者未註冊”。

我在 React 中的函式呼叫如下:

async function createPO(e) {
   e.preventDefault()
   const poeacct = e.target.elements[0].value
   const ponumber = e.target.elements[1].value
   const podate = e.target.elements[2].value
   let callOK = true
   try {
     await contract2.methods
       .createOrder('0xd2c4895e24095f23277df168f94a6c035813fe5d', poeacct, ponumber, podate)
       .call({ from: accounts[0] })
   } catch (err) {
     callOK = false
     setMess(err.message)
     console.log(err)
   }
   if (callOK) {
     await contract2.methods
       .createOrder('0xd2c4895e24095f23277df168f94a6c035813fe5d', poeacct, ponumber, podate)
       .send({ from: accounts[0] })

     setpouAcct(pouacct)
     setpoeAcct(poeacct)
     setpoNumber(ponumber)
     setpoDate(podate)
     setMess('Transaction successful')
   }
 }

這行得通,但它有點笨拙,所以我想知道是否有更好的方法。

第二。Web3 呼叫中“catch”返回的錯誤是 JSON,但有一個前綴:

Error: [object Object]
{
 "message": "VM Exception while processing transaction: revert Error: Order already exists",
 "code": -32000,
 "data": {
   "0x270bb8ddea630f3fc42a4f6196d7710cc50779a34994fd534a8ce139976b0ef5": {
     "error": "revert",
     "program_counter": 21219,
     "return": "0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001b4572726f723a204f7264657220616c7265616479206578697374730000000000",
     "reason": "Error: Order already exists"
   }

Error: [object Object]前綴阻止我解析“原因:”節點。如果我手動刪除前綴(即硬編碼)它可以工作。

我已經嘗試過substringslice和 JSON.parse 等,但我找不到解決方案。

類似於 JuliSmz 的答案,但我對神奇的 56 個字元串位置感到不舒服,因為我擔心它會變脆。我寫了這個小函式,它接受返回的錯誤對象catch

   function getRPCErrorMessage(err){
       var open = err.stack.indexOf('{')
       var close = err.stack.lastIndexOf('}')
       var j_s = err.stack.substring(open, close + 1);
       var j = JSON.parse(j_s);
       var reason = j.data[Object.keys(j.data)[0]].reason;
       return reason;
   }

我讓解析部分像這樣工作:

setMess(JSON.parse(err.message.substring(15).trim()).message)

仍然認為必須有一種更簡潔的方法來處理從 Web3 傳遞的錯誤。

引用自:https://ethereum.stackexchange.com/questions/86838