Solana程序事件发射测试中的错误处理方案咨询
解决Anchor事件测试中RPC异常静默吞掉的问题
原测试代码仅监听事件触发来resolve Promise,但未处理program.rpc.initialize()的执行异常——一旦RPC调用失败,Promise会一直处于pending状态,导致测试无限等待,异常被完全静默。
基础解决方案:捕获RPC执行错误
修改代码,在RPC调用时捕获异常并reject Promise,同时确保清理监听器:
anchor.setProvider(anchor.AnchorProvider.env()); const program = anchor.workspace.Events; it("Is initialized!", async () => { let listener = null; try { const [event, slot] = await new Promise(async (resolve, reject) => { listener = program.addEventListener("MyEvent", (event, slot) => { resolve([event, slot]); }); try { // 等待RPC调用完成,捕获执行阶段的错误 await program.rpc.initialize(); } catch (err) { // RPC出错时立即reject,并清理监听器 reject(err); await program.removeEventListener(listener); } }); await program.removeEventListener(listener); assert.isAbove(slot, 0); assert.strictEqual(event.label, "hello"); } catch (err) { // 兜底清理监听器,避免内存泄漏 if (listener) { await program.removeEventListener(listener); } // 抛出错误,让测试框架识别为测试失败 throw err; } });
进阶优化:增加事件超时处理
如果担心RPC成功但事件未正常发射的情况,可以添加超时机制,避免无限等待:
anchor.setProvider(anchor.AnchorProvider.env()); const program = anchor.workspace.Events; it("Is initialized!", async () => { let listener = null; let timeoutId = null; try { const [event, slot] = await new Promise(async (resolve, reject) => { listener = program.addEventListener("MyEvent", (event, slot) => { clearTimeout(timeoutId); // 事件触发后清除超时 resolve([event, slot]); }); // 设置5秒超时,超时后自动reject timeoutId = setTimeout(() => { reject(new Error("Timeout: MyEvent was not emitted")); program.removeEventListener(listener); }, 5000); try { await program.rpc.initialize(); } catch (err) { clearTimeout(timeoutId); // 出错时清除超时 reject(err); await program.removeEventListener(listener); } }); await program.removeEventListener(listener); assert.isAbove(slot, 0); assert.strictEqual(event.label, "hello"); } catch (err) { if (listener) { await program.removeEventListener(listener); } if (timeoutId) { clearTimeout(timeoutId); } throw err; } });
关键说明
- 同步处理RPC和事件:通过await RPC调用,确保任何执行错误都能被捕获并传递给Promise的reject
- 监听器清理:无论测试成功或失败,都必须移除事件监听器,避免影响后续测试用例
- 超时机制:可选但建议添加,防止因程序逻辑问题导致事件未发射的极端情况
内容的提问来源于stack exchange,提问作者zdev
相关产品推荐
相关产品推荐

