从 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 上获取异常

在Odoo中更新上下文8

通过上下文菜单将文本从edittext复制到剪贴板时出现异常?

(Ruby,Rails)模块和库中SELF的上下文......?

ruby Ruby中的DCI(数据,上下文,交互)范例