-
Notifications
You must be signed in to change notification settings - Fork 326
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
No way to handle 404s? #334
Comments
Reopening this as custom paths don't seem to handle 404s well after all. Even when 404 is returned Her prepares a model object but it has not attributes. I would expect it to return |
I notice the same thing, I would expect that Her returns |
i agree that returning nil makes more sense than an object with no attributes. the place this would be handled is in the Her::Middleware layer. when parsing the object, it's not accounting for 4xx codes as you noticed, and should. i'm doing some work at this level right now to handle json api compliant apis, so can take a look at this as well, or if you want to take a crack at PRing this yourself, that would be much appreciated. thanks for the report. |
the problem with returning nil is you have nothing to work with in the event of an error - but sometimes it's useful to see what was returned, the http status code ideally, all Her objects would have some simple way to see the http details one of the biggest knocks I hear against Her is the lack of transparency when something goes wrong |
I agree with ak47, sometimes you want to make decisions based on the status code. Like a 401 vs 422 vs 204. I am working on something right now where on a DELETE of a resource I get a 204 for a successful delete and a 422 for a unsuccessful delete. Now, I have no way of knowing whether or not the call was successful or not on the client side. Like ak47 said just having a hash of the details would relieve a lot of troubles I have with her. |
i agree there needs to be a way to distinguish between things working or not. however, i don't agree that http status codes are the way to do that. the her middleware layer is there to provide the adapter layer between the http details on the active model object that is returned. for a 404 specifically, nil is the most obvious, but the tradeoff would be that we wouldn't be able to include any additional info the server provides. the other possibilities would be a "NullModel" of some sort or making find raise an exception akin to how ActiveRecord does it. for a 422 or other 4xx responses, the way to determine whether or not the delete was success would be to query the errors object attached to the model. Her should probably add a generic error for 4xx cases and then add errors included by the server. |
object.response_errors => [{:id=>"bb78d697-7b3b-4780-8b45-3c0eadaabf95", |
I think @hubert is right here. System failure (including 401, 403, 404 and 5xx) should raise an exception. In those cases we can't rely on the API response to be sane. Content failure (e.g. 422 because invalid) should change model properties by passing through API error messages. I would suggest a small family of exceptions that follow the usual status code names ( Associates would sometimes need rescuing from fetch errors. Perhaps that should be configurable: belongs_to :country, foreign_key: :country_code, on_error: :raise For the model errors could I also suggest that we adopt |
Custom exceptions are good but theye're not for everyone. |
@marshall-lee yes, that would make sense for a processing error. The exceptions are meant for complete failures where we may not even have an object to store errors in. As @antonrd originally pointed out, creating a model object to communicate that there is no model object is too confusing. To address the original issue report properly: I think the value of a missing object should be nil, and the action of fetching a missing object should raise an exception. Ideally this would be done in a way that is very easy to ignore. For single associations the default behaviour on 404 would be to nullify and continue, but for an explicit find or fetch call we would let the caller handle the exception just as ActiveRecord does. |
You mean missing association objects? If yes I think the same.
As ActiveRecord throws |
Agreed that behaving like ActiveRecord is always going to be comforting. In Her it's easy to configure response error behaviour while setting up an api because in the end all requests are made by Her::API.setup url: "https://api.example.com", ignore_response_errors: [404] The maintainer would have to decide about default behaviour after an upgrade but rails gives us a good example: warn and deprecate one version ahead, then change the default behaviour in a way that is easy to undo. |
Yeah, I agree. |
@alvinschur Here's my solution. 1 Create faraday middleware to parse JSON data
2 Load custom parser instead of default one
3 When REST api returns 401 as http status, it raises ApiResponseHandler::UnauthorizedError
I hope this helps you. |
Thank you for the detailed answer and example. I am writing several libraries to access internal microservices. I see a few options for including the error handling code
Is it ok to include a middleware as described to handle the unauthorized error in her? This error handling sounds quite similar to handling 404 and other errors. Is it feasible to have one middleware handle a list of errors? |
|
I don't know best practice how about her's error handling but I'm handling 40x and 50x errors in one middleware(extract gem) like above example code. |
Did this conversation go any further? Found myself bumping up against it today, expecting find(unknown id) to Raise an exception but it swallows it. |
I am adding my solution here. What we did is as simple as: class ApplicationModel
include Her::Model
def self.find(params)
result = super
raise ActiveRecord::RecordNotFound unless result
result
end
# other stuff overrridden
end I hope this helps somebody else |
Is there a way to handle 404 status codes when an object was not found on the other side?
Say that we have a model Post and we have set things up so that we can call
Post.find(1)
and there is notPost
object withid=1
on the other side. Let's say the other API returnsnil
and status code 404. Her doesn't seem to consider the status code and rather complains with an error about thenil
. What is the right way to handle such situations?The text was updated successfully, but these errors were encountered: