2013-09-05 13 views
25

Se un sito Web restituisce un errore "503 servizio non disponibile", open-uri genera un'eccezione. Per esempio:Come posso gestire gli errori 503 con open-uri?

require 'open-uri' 
open('http://www.google.co.uk/sorry/?continue=http://www.google.co.uk/search%3Fq%3Dhello%26oq%3Dhello%26ie%3DUTF-8') 
# OpenURI::HTTPError: 503 Service Unavailable 
# ... 

Tuttavia, se si allora visita in un browser web, in realtà visualizza una pagina con un CAPTCHA e non un errore.

Come posso essere sicuro che open-uri non si limita a lanciare questa eccezione, ma in realtà gestisce la risposta e mi fornisce il contenuto della pagina?

risposta

46

OpenURI::HTTPError hanno un attributo io che è possibile ispezionare per ottenere ciò che si desidera. io è un oggetto StringIO con diversi metodi singleton definiti su di esso (status per esempio):

require 'open-uri' 
begin 
    open('http://www.google.co.uk/sorry/?continue=http://www.google.co.uk/search%3Fq%3Dhello%26oq%3Dhello%26ie%3DUTF-8') 
rescue OpenURI::HTTPError => error 
    response = error.io 
    response.status 
    # => ["503", "Service Unavailable"] 
    response.string 
    # => <!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n<html DIR=\"LTR\">\n<head><meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\"><meta name=\"viewport\" content=\"initial-scale=1\">... 
end  

Tuttavia per questo compito il modulo Net::HTTP è probabilmente un'alternativa migliore:

require 'net/http' 
response = Net::HTTP.get_response(URI.parse('http://www.google.co.uk/sorry/?continue=http://www.google.co.uk/search%3Fq%3Dhello%26oq%3Dhello%26ie%3DUTF-8')) 
response.code 
# => "503" 
response.body 
# => "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n<html DIR=\"LTR\">\n<head><meta http-equiv=\"content-type\" content=\"text/html; ... 
+1

Grazie! Ho letto la tua risposta alla domanda prima di modificarla, stavo leggendo le eccezioni e non dovrebbero essere utilizzate per condizioni comuni. Quindi sarebbe meglio usare net/http invece di open-uri in quanto significa che non devo usarne uno? –