Check Ruby HTTP response for success

For Net::HTTP, yes, checking the class of the response object is the way to do it. Using kind_of? (aliased also as is_a?) is a bit clearer (but functionally equivalent to using <):

response.kind_of? Net::HTTPSuccess

Calling value on response will also raise a Net::HTTPError if the status code was not a successful one (what a poorly named method…).

If you can, you may want to consider using a gem instead of Net::HTTP, as they often offer better APIs and performance. Typhoeus and HTTParty are two good ones, among others.


You can take advantage of Ruby's case statement which idiomatically performs class comparisons, thanks to its use of === under the hood.

Here's an example from a JSON client that catches particular errors but otherwise just returns the server's message:

  case response
    when Net::HTTPSuccess
      JSON.parse response.body
    when Net::HTTPUnauthorized
      {'error' => "#{response.message}: username and password set and correct?"}
    when Net::HTTPServerError
      {'error' => "#{response.message}: try again later?"}
    else
      {'error' => response.message}
  end

Note above Net::HTTPResponse parent classes (e.g. Net::HTTPServerError) work too.


If all you're looking to grab is the HTTP status code of an external API or website, then try Net::HTTP.get_response.

Net::HTTP.get(url) returns a string. You won't be able to easily parse the header response from it:

url = URI('http://example.com')
string_response = Net::HTTP.get(url)
# => "<!doctype html>\n<html>\n<head>\n    <title>Example Domain</title>\n\n    <meta charset=\"utf-8\" />\n    <meta http-equiv=\"Content-type\" content=\"text/html; charset=utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n    <style type=\"text/css\">\n    body {\n        background-color: #f0f0f2;\n        margin: 0;\n        padding: 0;\n        font-family: \"Open Sans\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n        \n    }\n    div {\n        width: 600px;\n        margin: 5em auto;\n        padding: 50px;\n        background-color: #fff;\n        border-radius: 1em;\n    }\n    a:link, a:visited {\n        color: #38488f;\n        text-decoration: none;\n    }\n    @media (max-width: 700px) {\n        body {\n            background-color: #fff;\n        }\n        div {\n            width: auto;\n            margin: 0 auto;\n            border-radius: 0;\n            padding: 1em;\n        }\n    }\n    </style>    \n</head>\n\n<body>\n<div>\n    <h1>Example Domain</h1>\n    <p>This domain is established to be used for illustrative examples in documents. You may use this\n    domain in examples without prior coordination or asking for permission.</p>\n    <p><a href=\"http://www.iana.org/domains/example\">More information...</a></p>\n</div>\n</body>\n</html>\n"

string_response.class
# => String
string_response.kind_of? Net::HTTPSuccess
# => false

status_response = Net::HTTP.get_response(url)
# => #<Net::HTTPOK 200 OK readbody=true>
status_response.class
# => Net::HTTPOK
status_response.kind_of? Net::HTTPSuccess
# => true