Ruby URL.parse错误

时间:2011-09-21 05:35:01

标签: ruby exception net-library

这是我的红宝石程序

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而不是接受并继续该程序?

3 个答案:

答案 0 :(得分:10)

如果你说u = URI.parse('http://google.com'),你会得到一个URI::HTTPu.port的默认值为80.如果你说u = URI.parse('google.com'),你会得到使用URI::Generic的{​​{1}}后面u.portnil 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