使用ethereum.on监听链切换时如何捕获MetaMask未添加目标链的报错
错误捕获失败原因
外层try/catch只能捕获同步执行阶段的错误,chainChanged事件回调属于异步触发逻辑,MetaMask抛出的RPC错误是provider内部的异步异常,不会冒泡到外层同步代码块,因此外层捕获逻辑无效。
解决方案
方案1:监听EIP-1193 provider的error事件(适配所有切链场景)
所有符合EIP-1193标准的钱包provider(包括MetaMask)都会将内部异步错误通过error事件对外通知,监听该事件即可同时捕获用户手动在MetaMask插件内切链、程序触发切链两种场景下的未识别链报错:
// 原有链切换监听逻辑 ethereum.on('chainChanged', (chainId) => { // 正常链切换业务逻辑 }) // 新增provider全局错误监听 ethereum.on('error', (error) => { // 优先用错误码4902判断未识别链,比文本匹配更可靠 if (error.code === 4902 || error.message.includes('Unrecognized chain ID')) { // 提取未识别的链ID const targetChainId = error.message.match(/0x[a-fA-F0-9]+/)?.[0] if (targetChainId) { // 调用添加链逻辑 addEthereumChain(targetChainId) } } }) // 示例:添加新链到MetaMask的方法 async function addEthereumChain(chainId) { try { await ethereum.request({ method: 'wallet_addEthereumChain', params: [ { chainId: chainId, // 对应链的配置参数,示例为Polygon主网配置 chainName: 'Polygon Mainnet', rpcUrls: ['https://polygon-rpc.com/'], nativeCurrency: { name: 'MATIC', symbol: 'MATIC', decimals: 18 }, blockExplorerUrls: ['https://polygonscan.com/'] } ] }) } catch (addError) { // 处理用户拒绝添加链等异常 console.error('添加链失败:', addError) } }
方案2:程序主动触发切链时直接捕获
如果你是通过代码调用wallet_switchEthereumChain触发切链,直接在异步调用处添加try/catch即可:
async function switchTargetChain(chainId) { try { await ethereum.request({ method: 'wallet_switchEthereumChain', params: [{ chainId: chainId }], }) } catch (switchError) { if (switchError.code === 4902) { // 未添加对应链,调用添加逻辑 addEthereumChain(chainId) } } }
内容的提问来源于stack exchange,提问作者Mariusz Sidorowicz
相关产品推荐
相关产品推荐

