Is there a way to get response on error with HTTPClient in Ruby? - ruby

I'm using the HTTPClient ruby library for making some basic http requests to a REST service I have develop and im wondering now how can I get the response from the service when an error occurred (a status code like 400 or 500 is returned from the service).
What my service does is return the stock of a product in a center, so it takes two parameters (in the url): a product id and a center id. When I call this service passing correct product and center ids the service returns me a 200 - OK status and the stock of the product (for example, 8.0 indicating there are 8 units of the product in that center). However, if I pass a wrong product id (one that is not in our database) the service returns 400 - Bad Request and an error message indicating that the id does not exists.
So I have a method like the following in Ruby
def stock(product, location)
response = #client.get_content("stock/#{product}/#{location}")
end
#client is an instance created with HTTPClient.new that I have configured. On passing ''right'' arguments it returns me what I want so it is well configured
My problem now is that when the service returns an error status code an HTTPClient::BadResponseError exception is thrown and I'm not able to retrieve this error in the response variable.
Is there a way to get the response from the service, no matter which status code it returns? I tried using begin...rescue and I can get some information like the status code and the reason phrase, but not the content of the response (the error message)

You're using get_content which skips a few steps and returns the content. Instead step back and use get which will return a more complete response structure that includes, among other things, the status field you want:
def stock(product, location)
response = #client.get("stock/#{product}/#{location}")
body = response.body
status = response.status
end

Related

I am getting false in API query with code 200 with ruby

Friends, I can't understand what's going on, I'm new to programming.
#Create Employee
#manter_user = Crud.new (my class)
#Create
$response = #manter_user.create(my method)
puts "Response is: #{$response}"
puts "Create Response HTTP code 200: #{$response.code == 200}"
end
crete ok
Response is: {"status":"success","data":{"name":"Kip","salary":8037.4700000000002546585164964199066162109375,"age":63,"id":7435},"message":"Successfully! Record has been added."}
**Create Response HTTP code 200: true**
#list
#id = $response.parsed_response["data"]["id"]
puts "#id: #{#id} retornado é o mesmo préviamente criado..."
retrieve_response = #manter_user.retrieve(#id)
puts "Retrieve Response HTTP code 200: #{retrieve_response.code == 200}"
end
List
**Retrieve Response HTTP code 200: false**
As I mentioned in my previous Answer and the comments below.
The dummy API you are using does not actually store the records you are creating it just provides a dummy response.
These are fake online REST APIs for testing and prototyping sample applications that use rest calls to display listings and crud features. This rest api tutorials, faking a server, and sharing code examples can all be used.
Methods provided by the API:
Create - You can "create" a record and receive a fictional response but the record is not persisted.
{"status":"success","data":{"name":"Alva","salary":12,"age":33,"id":1488},"message":"Successfully! Record has been added."}
Retrieve an individual record - You can retrieve a single record up to id 24 (a fixed list of records are available). Response differs from other methods. (This will result in a failure of verifying a 200 HTTP status code if you use an id > 24, which would be the case if you are using the id from the previously created record (also see below for another reason))
{"status"=>"success", "data"=>{"id"=>9, "employee_name"=>"Colleen Hurst", "employee_salary"=>205500, "employee_age"=>39, "profile_image"=>""}, "message"=>"Successfully! Record has been fetched."}
Update - You can "update" a record with any id and receive a fictional response but the response is malformed JSON making it effectively useless.
{"status"=>"success", "data"=>{"{\"name\":\"Cassia\",\"salary\":\"100000\",\"age\":\"24\"}"=>nil}, "message"=>"Successfully! Record has been updated."}
Delete - You can "delete" a record with any id and receive a fictional response.
{"status"=>"success", "data"=>"78", "message"=>"Successfully! Record has been deleted"}
There is no way using this dummy API that you can actually test the full lifecycle of record due to the way it is constructed.
Additionally it appears this API is in the process of being torn down:
They are trying to sell the domain and associated code
The page regularly shows that it is down, suspended, or under maintenance
They recently have implemented request throttling which is now resulting in a HTML response of "Too Many Requests" which will make it more difficult to use for basic testing. (This will also result in a failure if verifying a 200 HTTP code response)

REST HTTP Status Code Best Practice for validation API

I am creating a simple API to validate a membership. Client will have to input a String ID and Server will check if the ID is a valid member of our, lets say, community. The ID must be numeric only, with length 10.
Quite simple right?
If the ID is a valid, of course we will return HTTP Status Code OK.
If the ID is contains alfabet, or less/more than 10, then we will return HTTP Status Code BAD REQUEST.
The question is, what is the best practive HTTP Status Code to return when the ID is numeric and length = 10, but is NOT a member of our community? and why is that.
The endpoints of a REST API are normally resources on which you act using HTTP methods like GET,PUT,POST,DELTE. When you do it like that, its much easier to decide which HTTP status to return.
So may be you could make an endpoint
/member/{id}
if a member with this id exists, return HTTP 200 and if you want some JSON with basic member info
if the id is valid, but no member exists, return HTTP 404 - NOT FOUND
if the id is not valid, length !=10 or contains invalid chars, return a HTTP 400 BAD REQUEST
Here you can find more about REST API design

HTTP - Status Code

I'm using Spring Boot and controllers I'm feeling difficulty to treat some errors, for this reason I have some questions about the most appropriate status for each of the following situation:
PUT Object no Id
Put the URL localhost:8080/users/1 with a JSON without the Id attribute.
PUT Object with different parameter Id
Put the URL localhost:8080/users/1 with a JSON with Id 2, ie, different from what was passed in the parameter.
GET with invalid parameter
GET on the URL localhost:8080/users/search?sex=ABC, or an invalid sex for the system (the correct would be sex = male or female?).
JSON POST with id
Performing a POST in order to persist the data (create) but with id.
Case 1. Id is in the uri : no error
Case 3. "400 Bad request" is acceptable. (client should not retry the exact same request)
Cases 2. and 4. Just ignore the Id from the body and return 200 or return a "400 Bad Request"
Note that the id shouldn't be seen as an attribute of the resource: it is a part of the resource identifier.

How to pass django error status to ajax

Using django rest framework with backbone.
Current situation:
Whenever an ajax call fails, django responds through get_error_response
As soon as get_error_response gets invoked, django raises a error on client side too, as i am not handling this error in django(server) side.
views.py snippet
def get_error_response(self):
return Response(
self.serializer.errors, status=status.HTTP_400_BAD_REQUEST
)
Requirement:
I want to be able to pass all error statuses to $ajax.fail() promise, and handle it there on client side, thereby enabling me to show the error messages to user.
Note:something like the code given below is what i am expecting. But the problem is, this response would got to $ajax.done promise(), wheras i want it in $ajax.fail() promise
def get_error_response(self):
return Response({
"msg":self.serializer.errors, "error_status":status.HTTP_400_BAD_REQUEST
})
Do ask if more clarity is required.
No matter if you're using a Response from Django Rest Framework or the normal Django HttpResponse you always need to pass the keyworded argument status in order to make the response actually have the correct status code thus invoking the correct handler in your front end code.
What your last example does is only passing a data or content argument which is making the response class default to a 200 status code.
return Response(your_data, status=404)

wireload / Ratatosk : How to make POST requests?

In my Cappuccino frontend I'm using Ratatosk to make queries to a RESTful JSON-based API.
When I create a new resource with
[myNewResource ensureCreated];
my backend returns the status code 201 and a Location header with the URI of the newly created resource. The response body is empty. As far as I know, that's the way a REST API should react to successful POST requests.
But upon receiving the response, Ratatosk calls
- (void)connection:(CPURLConnection)aConnection didReceiveData:(CPString)data
(in WLRemoteLink.j) and tries to decode the response body. This throws an error because the response body is empty. As a consequence, the request is repeated infinitely.
How should I go about this? Am I supposed to return the whole resource in the response body?
EDIT:
Returning the ID in the response solved the problem, like
{"id":1}
Ratatosk expects the status code 204 (no content) if the response is to be empty. Otherwise it expects the full representation of the resource which was just created (which it uses to populate server side dynamic properties locally like created_at).

Resources