这是我的红宝石程序
require 'net/http'
require 'uri'
begin
url = URI.parse("http://google.com")
rescue Exception => err
p err
exit
end
http = Net::HTTP.new(url.host, url.port)
res = http.head("/")
p res.code
它工作正常,但如果我从URL.parse()中删除http://,它会给我这个错误:
/usr/lib/ruby/1.9.1/net/http.rb:1196:in `addr_port': undefined method `+' for nil:NilClass (NoMethodError) ...
from /usr/lib/ruby/1.9.1/net/http.rb:1094:in `request'
from /usr/lib/ruby/1.9.1/net/http.rb:860:in `head'
这是处理异常的正确方法吗?
我知道URL可能不正确,但它应该引发异常URI :: InvalidURIError而不是接受并继续该程序?
答案 0 :(得分:10)
如果你说u = URI.parse('http://google.com')
,你会得到一个URI::HTTP
,u.port
的默认值为80.如果你说u = URI.parse('google.com')
,你会得到使用URI::Generic
的{{1}}后面u.port
将nil
u.host
。
所以,当你这样做时:
url = URI.parse('google.com')
http = Net::HTTP.new(url.host, url.port)
你真的这样做了:
http = Net::HTTP.new(nil, nil)
和Net::HTTP
根本不喜欢这样。你可以尝试这样的事情:
if(str.to_s.empty?)
# complain loudly about a missing str
end
begin
url = URI.parse(str)
url = URI.parse('http://' + str) if !url.scheme
if(url.scheme != 'http' && url.scheme != 'https')
# more complaining about bad input
end
http = Net::HTTP.new(url.host, url.port)
#...
rescue URI::Error => e
# even yet more complaining
end
这种事情应该完全绕过这个例外,并涵盖一些你可能感兴趣的事情。
答案 1 :(得分:3)
你必须专门捕捉URI::InvalidURIError
,因为它不是Exception
的后代。参见:
irb(main):002:0> URI::InvalidURIError.is_a?(Exception)
=> false
所以代码的修复程序是:
begin
url = URI.parse("http://google.com")
rescue URI::InvalidURIError => err
p err
exit
end
答案 2 :(得分:1)
正确的方法是不要让任何异常发生,而是事先检查你的情况。像这样:
require 'net/http'
require 'uri'
begin
url = URI.parse("http://google.com")
rescue URI::InvalidURIError => err
p err
exit
end
if url.host && url.port
http = Net::HTTP.new(url.host, url.port)
res = http.head("/")
p res.code
else
p 'Error parsing url'
end