Due to the “concurrent requests” support, httpx
does not raise exceptions on errors. A call to HTTPX
will therefore always return a response (or several). However, the response might be an error response (of the class HTTPX::ErrorResponse
):
response = HTTPX.get("https://www.google.com")
puts response.class #=> "HTTPX::Response"
response = HTTPX.get("https://someunexistingpage.com")
puts response.class #=> "HTTPX::ErrorResponse"
A simple strategy is to query the response for an error:
response = HTTPX.get("https://unreachable.com")
if response.error #=> yes, it's `Errno::CONNREFUSED`
# ...
end
response = HTTPX.get("https://en.wikipedia.org/wiki/The_Godfather_Part_IIII") #=> 404
if response.error #=> yes, it's `HTTPX::HTTPError`
# ...
end
response = HTTPX.get("https://en.wikipedia.org/wiki/The_Godfather_Part_III") #=> 200
if response.error #=> no, it's `nil`
# ...
end
You can choose to bubble up such exceptions by calling response.raise_for_status
. This will raise an exception if the response wraps an exception or if the response contains an HTTP Error Status Code (4xx or 5xx).
response = HTTPX.get("https://unreachable.com")
response.raise_for_status #=> raises Errno::CONNREFUSED
response = HTTPX.get("https://en.wikipedia.org/wiki/The_Godfather_Part_IIII") #=> 404
response.raise_for_status #=> raises HTTPX::HTTPError
response = HTTPX.get("https://en.wikipedia.org/wiki/The_Godfather_Part_III") #=> 200
response.raise_for_status #=> nil
You can also use pattern-matching (note: ruby 3 only) to check for errors:
case (response = HTTPX.get("https://unreachable.com"))
in {status: 200..299}
# success
in {status: 400..}
# http error
in {error: error}
puts error.class #=> "Errno::CONNREFUSED"
end