为什么ruby不提出异常?

为什么ruby不提出异常?,ruby,exception-handling,Ruby,Exception Handling,我有以下代码: require 'open-uri' class CustomException < StandardError;end def file f = Kernel.open('http://i.dbastatic.dk/images/2/68/500656768_20012012182407_0401_2.jpg') return f rescue => e raise CustomException.new(e.message) end 我得到: N

我有以下代码:

require 'open-uri'

class CustomException < StandardError;end

def file
  f = Kernel.open('http://i.dbastatic.dk/images/2/68/500656768_20012012182407_0401_2.jpg')
  return f
rescue => e
  raise CustomException.new(e.message)
end
我得到:

NoMethodError:nil的未定义方法“body”

而不是来自OpenURI的带有404错误消息的CustomException。奇怪的是,如果我这样做:

begin
  f = file
  f.body
rescue CustomException
  puts "rescued it!"
end

然后它工作了,我得到了CustomException,在它尝试执行.body之前,我可以捕获它。我不明白为什么?如何更改文件方法以达到预期效果?

只需稍作修改即可显示问题:

require 'open-uri'

def file
  f = Kernel.open('fill_in_some_url_that_returns_a_404')
  return f
rescue => e
  puts e.message
  1 ##<<---- inserted
end

file.body
我也犯了同样的错误

您确定在两个调用中使用相同的url吗?如果可以打开url,则会重新运行有效对象


事实上,如果没有更多的代码,我看不到你的问题

您可以检查代码中的一项内容:

如果定义变量和方法
文件
,则得到变量。见下面的例子。也许这就是问题所在

file = nil
def file
  1
end

file.body   #undefined method `body' for nil:NilClass (NoMethodError)
file().body #undefined method `body' for 1:Fixnum (NoMethodError)

为了确保获得该方法,您可以尝试
file()

这可能就是您想要的:

require 'open-uri'

def file(url)
 begin
  Kernel.open(url)
 rescue => e
  puts e.message
 end
end
让我们先尝试一个有效的url:

f = file('http://www.google.com/')
puts f.read if !f.nil?
现在让我们使用返回404的url进行尝试:

f = file('http://www.google.com/blahblah')
puts f.read if !f.nil?

编辑:当对不存在的URL调用时,代码会引发两个错误。“file”方法会引发OpenURI::HTTPError,而“body”方法会引发NoMethodError,因为它是在nil上调用的。在第一个使用示例中,在一条语句中引发这两个错误。在第二个使用示例中,错误是连续的。尽管如此,它们还是应该产生同样的结果,它们对我来说也是如此

我想你把自己弄糊涂了。您展示的唯一一个似乎能够说明问题的代码是:

require 'open-uri'

class CustomException < StandardError;end

def file
  f = Kernel.open('http://www.google.com/blahblah')
  return f
rescue => e
  raise CustomException.new(e.message)
end

begin
  file.body
rescue CustomException
  puts "rescued it!"
end

对不起,我的错,这是个坏例子。我最终过度简化了我真正想做的事情。现在我编辑了我的问题,以便更好地符合实际情况。。。请再看一眼:-)好的,但我希望第一个会中断进一步的执行,并被提出-你呢?我应该做些什么来改变file方法,这样我仍然可以执行file.body,并且仍然可以得到第一个异常是的,执行在第一个异常之后停止。一般来说,您需要缩小要从中恢复的异常范围。例如,从一个命名错误中恢复过来没有多大意义。只需检查方法定义之外的nil对象。
f = file('http://www.google.com/blahblah')
puts f.read if !f.nil?
require 'open-uri'

class CustomException < StandardError;end

def file
  f = Kernel.open('http://www.google.com/blahblah')
  return f
rescue => e
  raise CustomException.new(e.message)
end

begin
  file.body
rescue CustomException
  puts "rescued it!"
end
require 'open-uri'

class CustomException < StandardError;end

def file
  f = Kernel.open('http://www.google.com/blahblah')
  return f
rescue => e
  raise CustomException.new(e.message)
end

begin
  file.body
rescue CustomException => e
  puts "rescued it!", e.message
end