Web3.js sendSignedTransaction错误无法捕获,求解决方法
问题解决:web3.js sendSignedTransaction 错误无法被try-catch捕获的修复方案
核心原因
web3.js的sendSignedTransaction在处理格式完全错误的交易时,可能会出现两种绕过async函数try-catch的情况:
- 内部解析交易时同步抛出错误,未被封装为Promise的reject
- 返回的
PromiEvent(Promise+EventEmitter)触发的error事件未被监听,导致未捕获异常
修复方案
1. 前置校验过滤非法输入
先拦截明显不符合以太坊签名交易格式的输入,避免进入web3的解析流程:
- 必须是
0x开头的十六进制字符串 - 长度需满足最低要求(签名交易至少包含基础字段,对应十六进制长度远大于20)
2. 用Promise完整包装交易流程
统一处理同步错误、Promise reject、EventEmitter的error事件,确保所有错误都能被try-catch捕获
修改后的代码
async sendTransaction( nodeName: string, signedTx: string, userAgent: string, ): Promise<SendTransactionResponseDTO> { try { // 前置校验:拦截非法格式的签名交易 if (!/^0x[0-9a-fA-F]+$/.test(signedTx) || signedTx.length < 20) { throw new Error("Invalid signed transaction format"); } const web3 = await this.web3Service.getWeb3Instance(nodeName); // 用Promise包装,覆盖所有错误场景 const receipt = await new Promise((resolve, reject) => { try { const promiEvent = web3.eth.sendSignedTransaction(signedTx); // 监听EventEmitter的error事件 promiEvent.on('error', reject); // 处理Promise的成功/失败 promiEvent.then(resolve).catch(reject); } catch (syncErr) { // 捕获同步抛出的解析错误 reject(syncErr); } }); const hash = receipt.transactionHash; await this.saveTransaction(signedTx, receipt, userAgent, nodeName); return { txId: hash.toString() }; } catch (e) { this.logger.error(e); captureException(e); throw new HttpException('Dummy exception', 400); } finally { console.log("Finally"); } }
说明
原代码崩溃是因为错误在web3内部的微任务(Immediate._onImmediate)中抛出,未被转化为Promise的reject。通过Promise包装并显式监听error事件,可将所有错误统一纳入try-catch的捕获范围,避免程序崩溃。
内容的提问来源于stack exchange,提问作者kursatba
相关产品推荐
相关产品推荐

