views:

234

answers:

2

Hi,

I'm fetching some weather data from an online xml doc using Nokogiri, and I would like to set up a timeout for graceful recovery in case the source can't be reached...

My google searches show several possible methods for open-uri and Net::HTTP, but none specific to Nokogiri. My attempts to use those methods are failing (not too surprisingly):

begin
currentloc = ("http://api.wunderground.com/auto/wui/geo/WXCurrentObXML/index.xml?query=" + @destination.weatherloc)
currentloc.read_timeout = 10 # 
doc = Nokogiri::XML(open(currentloc))
rescue Timeout::Error
  return "Current weather for this location not available: request timed out."
end

returns "NoMethodError", and:

begin
currentloc = ("http://api.wunderground.com/auto/wui/geo/WXCurrentObXML/index.xml?query=" + @destination.weatherloc)
doc = Nokogiri::XML(open(currentloc), :read_timeout => 10)
rescue Timeout::Error
  return "Current weather for this location not available: request timed out."
end

returns "TypeError can't convert Hash into String"

Does Nokogiri support this kind of method (and if so... how?), or should I be looking at some other solution?

Thanks.

A: 

You can use the timeout module :

require 'open-uri'
require 'nokogiri'
require 'timeout'

begin
  timeout(10) do
    result = Nokogiri::XML(open(currentloc))
  end
rescue Timeout::Error
  return "Current weahter..."
end
Vincent
This appears to work (at least it doesn't break), but when I try to test it by disconnecting eth0, I'm getting a SocketError. I guess I need some sort of conditional test for that, too.Adding an extra rescue statement (rescue SocketError) is failing, however.Thanks
David Smith
Can you post your code so I can see for myself in greater detail?
Vincent
A: 

Response to Vincent's comment ^^^^^^

begin
  timeout(4) do
    result = Nokogiri::XML(open(currentloc))
    @doc = result
  end
rescue OpenURI::HTTPError
#rescue SocketError # no point if no net connection... 
  flash[:notice] = 'Current weather for this location is not available: network connection was not established.'
rescue Timeout::Error    
  flash[:notice] = 'Current weather for this location is not available: connection timed out.'
end
# if @doc.blank?
if @doc.xpath('/current_observation/station_id').text().blank?     
  flash[:notice] = 'Current weather for the specified location is unavailable.'
else
[does stuff it's supposed to when all is well]

Hi,

Thanks for responding again... as you can see I abandoned the 'rescure SocketError' after it occurred to me if there was no socket (connection) from the rails app server, the user wouldn't even see the page (though of course I could see it from the internal development mongrel server)!

I've tried "rescue OpenURI::HTTPError" but I don't think that quite covers it either. I addressed two contingencies, 1: case of no location specified, it falls back to a placeholder (code not included above) 2: case of an invalid location code entered, the source uri returns a 'blank' template xml.

Still a little unclear on how to test for and recover from an unreachable source uri though..

Thanks for your help!

David Smith