Search code examples
rubyrest-clientnet-http

Net::HTTP vs REST Client gem: How do they handle bad websites / 404


I was trying to access some websites using rest-client gem and I found a behavior that was puzzling to me. It has to do with using rest-client with a bad website, in this case, www.google.com/this_does_not_exist.

What I expected: That the code would run and the response object will have a 404 response code.

What actually happened: There was an exception and the code was terminated prematurely.

When I tried the same thing with the Net::HTTP library, I did get the expected result.

The question is: Is this behavior expected in rest-client? If so, how would you get back an object with a 404 response code when using with bad websites.

Here is the code from my irb:

2.2.1 :045 > uri = URI('http://www.google.com')
 => #<URI::HTTP http://www.google.com> 
2.2.1 :046 > response = Net::HTTP.get_response(uri)
 => #<Net::HTTPOK 200 OK readbody=true> 
2.2.1 :047 > response.code
 => "200" 
2.2.1 :048 > uri = URI('http://www.google.com/this_does_not_exist')
 => #<URI::HTTP http://www.google.com/this_does_not_exist> 
2.2.1 :049 > response = Net::HTTP.get_response(uri)
 => #<Net::HTTPNotFound 404 Not Found readbody=true> 
2.2.1 :050 > response.code
 => "404" 
2.2.1 :051 > uri = URI('http://www.google.com')
 => #<URI::HTTP http://www.google.com> 
2.2.1 :052 > response = RestClient.get('http://www.google.com')
 => <RestClient::Response 200 "<!doctype h..."> 
2.2.1 :053 > response.code
 => 200 
2.2.1 :054 > response = RestClient.get('http://www.google.com/this_does_not_exist')
RestClient::NotFound: 404 Not Found
    from /Users/piperwarrior/.rvm/gems/ruby-2.2.1/gems/rest-client-2.0.0/lib/restclient/abstract_response.rb:223:in `exception_with_response'
    from /Users/piperwarrior/.rvm/gems/ruby-2.2.1/gems/rest-client-2.0.0/lib/restclient/abstract_response.rb:103:in `return!'
    from /Users/piperwarrior/.rvm/gems/ruby-2.2.1/gems/rest-client-2.0.0/lib/restclient/request.rb:860:in `process_result'
    from /Users/piperwarrior/.rvm/gems/ruby-2.2.1/gems/rest-client-2.0.0/lib/restclient/request.rb:776:in `block in transmit'
    from /Users/piperwarrior/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/net/http.rb:853:in `start'
    from /Users/piperwarrior/.rvm/gems/ruby-2.2.1/gems/rest-client-2.0.0/lib/restclient/request.rb:766:in `transmit'
    from /Users/piperwarrior/.rvm/gems/ruby-2.2.1/gems/rest-client-2.0.0/lib/restclient/request.rb:215:in `execute'
    from /Users/piperwarrior/.rvm/gems/ruby-2.2.1/gems/rest-client-2.0.0/lib/restclient/request.rb:52:in `execute'
    from /Users/piperwarrior/.rvm/gems/ruby-2.2.1/gems/rest-client-2.0.0/lib/restclient.rb:67:in `get'
    from (irb):54
    from /Users/piperwarrior/.rvm/rubies/ruby-2.2.1/bin/irb:11:in `<main>'
2.2.1 :055 > 

Solution

  • From the GitHub README:

    • for result codes between 200 and 207, a RestClient::Response will be returned
    • for result codes 301, 302 or 307, the redirection will be followed if the request is a GET or a HEAD
    • for result code 303, the redirection will be followed and the request transformed into a GET
    • for other cases, a RestClient::Exception holding the Response will be raised; a specific exception class will be thrown for known error codes
    • call .response on the exception to get the server's response

    So yes, this is expected behavior, the response object can be retrieved with e.response.