从 V8 上下文中获取 ruby 异常
Posted
技术标签:
【中文标题】从 V8 上下文中获取 ruby 异常【英文标题】:Get ruby exception from V8 context 【发布时间】:2014-11-30 02:45:33 【问题描述】:context = V8::Context.new(timeout: 20000) do |context|
context['ForbidAccess'] = ->(message) throw NotImplementedError
end
begin
context.eval("ForbidAccess();")
rescue => e
puts "e.class = #e.class.name"
puts "e.causes = #e.causes"
puts "e.root_cause = #e.root_cause"
puts "e.root_cause.class = #e.root_cause.class"
end
控制台输出:
e.class = V8::Error
e.causes = [#<V8::Error: uncaught throw NotImplementedError>, #<ArgumentError: uncaught throw NotImplementedError>]
e.root_cause = uncaught throw NotImplementedError
e.root_cause.class = ArgumentError
如何访问 NotImplementedError 对象?
(NotImplementedError 只是为了展示。它将被包含消息等的自定义异常替换)
【问题讨论】:
如果您的问题没看错,您想知道如何访问调用它的 Ruby 代码中的 javascript 异常? 我使用了“投掷”而不是“提高”。就是这样。 【参考方案1】:你可能没有做你认为你正在做的事。 throw
关键字不适用于异常。它实际上是类似于其他语言的goto
的本地跳转。看到这个sn-p:
catch :done do
while true
array = [1,2,3]
for i in array
if i > 2
throw :done
end
end
end
end
它只是一个控制流结构,其中“捕获”对象必须与“抛出”对象匹配。但是你不能简单地捕捉所有的抛出并找出它是哪个对象。对于异常(如NotImplementedError
),正确使用的是raise
:
context = V8::Context.new(timeout: 20000) do |context|
context['ForbidAccess'] = ->(message) raise NotImplementedError
end
begin
context.eval("ForbidAccess();")
rescue => e
puts "e.root_cause = #e.root_cause.inspect"
# correctly prints #<NotImplementedError: NotImplementedError>
end
至于为什么你在那里看到ArgumentError
,很简单:一个throw 不能通过begin
-rescue
结构(从异常中拯救)。当未捕获的 throw 遇到救援时,会创建一个关于它的新异常。检查以下:
begin
throw "whatever"
rescue e
p e #=> ArgumentError: uncaught throw "whatever"
end
internally 会发生这种情况,所有 V8 库看到的都是 ArgumentError
弹出。
【讨论】:
我知道 Ruby 的 raise 和 JavaScript 的 throw,但显然我并没有完全清醒。非常感谢您指出这一点。另外,我没有帮助我在 ruby 之前几年编写 C#,它也使用 'throw' 作为 JavaScript :-)以上是关于从 V8 上下文中获取 ruby 异常的主要内容,如果未能解决你的问题,请参考以下文章
获取有关 Airflow on_failure_callback 上下文的异常详细信息
需要帮助设置后台托管对象上下文。在 FRC controllerDidChangeContent 上获取异常
通过上下文菜单将文本从edittext复制到剪贴板时出现异常?