You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Watir中封装Begin/Rescue至函数后无法捕获异常的问题求助

问题分析与解决方案

一、最初封装函数失效的原因

你第一次封装的函数之所以没生效,核心问题出在参数求值时机上:
当你调用exception_check(browser.select_list(:id => "P5500_P_NATIONALITY").select("Americans"))时,Ruby会先执行括号里的browser.select_list(...).select代码,再把结果传给函数。也就是说,异常在进入函数的begin块之前就已经触发了,自然不会被函数内部的rescue捕获。

你后来改成用yield传递代码块的思路是完全正确的——这样代码会在函数内部的begin块里执行,异常才会进入捕获范围。


二、为什么用yield后仍然没捕获到异常?

从你贴出的错误日志来看,抛出的异常确实是你指定要捕获的Watir::Exception::UnknownObjectException和Watir::Wait::TimeoutError,但rescue块没有生效,大概率是因为rescue块内部的代码本身出错了:

你的exception_check函数是一个独立的作用域,无法直接访问外部的browser、test_id这些局部变量。当rescue块尝试调用screenCapture(browser,...)或者log_fileWriter(...,test_id)时,会因为找不到这些变量而抛出NameError,这个新的异常会覆盖原本的Watir异常,让你误以为捕获逻辑失效。


三、修复方案

1. 传递必要变量到函数作用域

把browser和test_id作为参数传给异常处理函数,确保rescue块能访问到它们:

def exception_check(browser, test_id)
  yield
rescue Watir::Wait::TimeoutError, Watir::Exception::UnknownObjectException, Watir::Exception::NoValueFoundException
  puts "Error handling caught an exception: Relationships Page. See log."
  log_fileWriter("after_header","Relationship Page:",$exception_error_code,"2",test_id)
  screenCapture(browser,"Add Relationship",test_id)
end

# 调用时传入变量
exception_check(browser, test_id) { browser.select_list(:id => "P5500_P_NATIONALITY").select("Americans") }

2. 先验证基础捕获逻辑

如果还是不确定问题,可以先简化rescue块,排除其他代码的干扰,验证捕获功能是否正常:

def exception_check
  yield
rescue => e
  puts "Caught exception: #{e.class} - #{e.message}"
end

# 测试错误场景
exception_check { browser.text_field(:name => "qq").set("watir") }

如果这段代码能正常打印出异常信息,说明之前的问题确实出在rescue块里的log_fileWriter或screenCapture调用上。

3. 可选:使用实例变量(如果适合你的代码结构)

如果不想每次都传参数,可以把browser、test_id改成实例变量(比如@browser、@test_id),这样函数内部就能直接访问到它们。


内容的提问来源于stack exchange,提问作者bobbie_j

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 21:39:05