How does one properly check the response from Net::HTTP::Get (for example) for "success" (i.e., a 2xx return code)? The documentation seems to be sadly silent on this simple question.
I have:
response=Net::HTTP.new( host, port ).request my_get_request # details not important
After a bunch of Googling and near-random typing, I finally determined that this works:
response.class < Net::HTTPSuccess
Is that actually the canonical way to do it?
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With