Ruby URL.parse error - PullRequest
       1

Ruby URL.parse error

4 голосов
/ 21 сентября 2011

Вот моя рубиновая программа

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

Работает нормально, однако, если я удаляю http: // из URL.parse (), выдает эту ошибку:

/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 ]

10 голосов
/ 21 сентября 2011

Если вы скажете u = URI.parse('http://google.com'), вы получите URI::HTTP назад, а u.port будет иметь значение по умолчанию 80. Если вы скажете u = URI.parse('google.com'), вы получите URI::Generic обратно с 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

Подобные вещи должны полностью обходить исключение и охватывать несколько других вещей, которые могут вас заинтересовать.

3 голосов
/ 21 сентября 2011

Вы должны специально поймать 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
1 голос
/ 21 сентября 2011

Правильный способ - не допустить возникновения какого-либо исключения, а заранее проверить ваши условия.Как это:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...