Reputation: 7894
I recently switched from Ruby's Net:HTTP class to rest-client 1.6.7.
I find it a lot easier to form requests, but unlike Net:HTTP request, when rest-client gets anything other than a 200, the request dies. I've tried putting a breakpoint directly after the RestClient.get, and it never gets hit - so I'm doing something wrong.
def get_member_using_card
resource = "#{@settings_app_uri}api/v1/card/#{self.member_card_num}?token=#{@settings.api_key}"
response = RestClient.get resource
if response.code == 200
card = JSON.parse(response.body)
self.customer_id = card['card']['customer_id']
else
return 0
end
end
Which results in this stacktrace:
RestClient::ResourceNotFound - 404 Resource Not Found:
/Users/tim/.rvm/gems/ruby-1.9.2-p290/gems/rest-client-1.6.7/lib/restclient/abstr
act_response.rb:48:in `return!'
/Users/tim/.rvm/gems/ruby-1.9.2-p290/gems/rest-client-1.6.7/lib/restclient/reque
st.rb:230:in `process_result'
/Users/tim/.rvm/gems/ruby-1.9.2-p290/gems/rest-client-1.6.7/lib/restclient/reque
st.rb:178:in `block in transmit'
/Users/tim/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/net/http.rb:627:in `start'
/Users/tim/.rvm/gems/ruby-1.9.2-p290/gems/rest-client-1.6.7/lib/restclient/reque
st.rb:172:in `transmit'
/Users/tim/.rvm/gems/ruby-1.9.2-p290/gems/rest-client-1.6.7/lib/restclient/reque
st.rb:64:in `execute'
/Users/tim/.rvm/gems/ruby-1.9.2-p290/gems/rest-client-1.6.7/lib/restclient/reque
st.rb:33:in `execute'
/Users/tim/.rvm/gems/ruby-1.9.2-p290/gems/rest-client-1.6.7/lib/restclient.rb:68
:in `get'
Can someone tell me how to properly evaluate the response code and keep this exception from happening...?
Upvotes: 41
Views: 53537
Reputation: 17157
See heading Exceptions on http://rubydoc.info/gems/rest-client/
RestClient.get 'http://example.com/resource'
➔ RestClient::ResourceNotFound: RestClient::ResourceNotFound`
begin
RestClient.get 'http://example.com/resource'
rescue RestClient::ExceptionWithResponse => e
e.response
end
➔ 404 Resource Not Found | text/html 282 bytes
Upvotes: 62
Reputation: 13
I believe the best way to handle exceptions of an API client is to get the original error message thrown by the API endpoint. Here is an example code to handle that with RestClient
require 'json'
def get_call
begin
standard_response = {body: nil, success: false, message: ''}
response = RestClient.get('https://example.com/api/v1/xx', headers={'Authorization' => 'AbcDef xxx'})
standard_response[:success] = true
standard_response[:body] = JSON.parse(response.body)
rescue RestClient::ExceptionWithResponse => e
http_body = JSON.parse(e.http_body) # This is the original response from the API endpoint. e.g. {'message': 'Reason for the failure'}
meaningful_error_message = http_body['message'].nil? ? e.message : http_body['message'] # if {'message': 'error message'} is the format of your API
standard_response[:message] = meaningful_error_message
end
standard_response
end
Upvotes: 1
Reputation: 815
Beautiful way to handle the exceptions in rest client.
For more info do check rest-client#response-callbacks-error-handling
RestClient.get('http://example.com/resource') { |response, request, result, &block|
case response.code
when 200
p "It worked !"
response
when 423
raise SomeCustomExceptionIfYouWant
else
response.return!(&block)
end
}
Upvotes: -2
Reputation: 1721
Also in the same documentation @wich pointed to, you can pass a block to RestClient.get such that it will not throw an exception on non-200 response codes:
# Don't raise exceptions but return the response
RestClient.get('http://example.com/resource'){|response, request, result| response }
See the "Result Handling" section from the documentation.
Upvotes: 27
Reputation: 1651
There are several errors that could happen, specific exception types like Errno::EHOSTUNREACH or the more generic ExceptionWithResponse. Check the readme for more info.
Upvotes: 1