I've got a bunch of XHR actions in a controller, which return some HTML to insert into the page. If the response is an error, then it puts the output into a special error div. So far, nothing particularly interesting.
However, this general process doesn't work for Rails' exception handling. If I raise an exception in my XHR actions, I get the generic 500 error handler output in my error div, which looks a bit horrific. While I can catch all possible exceptions in my action and render a more appropriate error, I lose the standard exception logging and notification, which sucks.
So, the only solution I can think of is being able to specify a different 500 handler HTML fragment to use for these specific actions, but I'm not finding much. Anyone got any ideas?
You should be able to check for the 500 status code in your javascript handler and display a generic message like "Server Problem". If there are cases where a more specific error message would be useful to an end user in a production environment, you'll have to catch those exceptions with a rescue_from clause. If you really want to prevent the 500 page from showing, you can override the rescue_action_in_public method on your XHR controller.
Related
Stack: Ruby 2.2, Rails 4.2, and Honeybadger.
I've been working on the error handling code for my site. I've noticed that error handling has become a real mess though out the site, and I've been looking for a way to standardize error handling.
The following "generic" error types have been found:
Record/resource not found
Failure to save record
Validation issues
Rights/Permissions errors
Other (Usually probing bots, double clicks, or WTF?)
With the following resulting actions.
Notify Error Collating resource (maybe)
Save data; if a particularly long form input
Response: Redirect to an error page (flash[:error]='?')
Response: Return a JSON string (AJAX requests)
Response: Various Status codes http 3xx, 4xx, 5xx
Customized message for developer (maybe); quite lengthy in some cases
Customized message for user
Silently do nothing
And then process issues
Roll back
return (exiting the action; and not allowing further action)
Does anyone know of a Gem/Module/Tutorial that handles these collective issues holistically?
Thank you in advance!
-daniel
I think the best answer, is to throw an exception
Controller code is responsible for getting the parameters, sanitizing them, role/safety checks, making calls to GET data (this should be business logic), and the preparing the data for export back to the browser.
I'll add on to this handling exceptions from the code.
Then business logic, should throw an error should something fatalistic happen.
I notice OpenRasta.Core has an HtmlErrorCodec which is responsible for rendering a the server error page sent out when a handler throws an Exception.
When I make an JSON Ajax request to an exception throwing handler this Codec is selected and the exception is rendered as HTML.
I have tried to register my own IMediaTypeWriter for IList<Error> with MediaType("application/json") so I can send back JSON to the browser, but it seems to be ignored. Can anyone help?
Thanks
Neil
If there is an error, indeed a codec with IList will be selected, but will follow the normal conneg for a type.
I'd suggest having a look at the request log and finding out how and why the html codec gets selected (I'd suspect with my remote debugging tunnel vision that you may have a browser sending the equivalent of Accept: text/html,application/json, at which point OR doesn't really know which of the two is acceptable, which is probably a bug as we register text/html with a q of 1 where it should be 0.5). If that's indeed what the problem is, the solution is to remove the registration for the html error codec, which you can do by providing your own DependencyRegistrar.
Can you just catch your exceptions, wrap them in a type and do something like:
ResourceSpace.Has.ResourcesOfType<MyErrorWrapper>().WithoutUri.AsJsonDataContract()
Here is a simple question. Is there any possibility of, if in any case there's an error in an application and the server show us an error page, instead redirect everything to a default page ?
Covering all errors.. is that possible ?
Grails already does this for you. If an exception bubbles up to the container, it gets handled as an HTTP 500 (Internal Server Error). With conf/URLMappings.groovy you can control what happens what happens when error statuses occur.
Here's the default mapping for 500 responses (from conf/URLMappings.groovy):
"500"(view:'/error')
This tells the application to render the error view, which is located in views/error.gsp. If you want to change this, you can. You could redirect to a controller/action if you want:
// will go to 'custom' action of ErrorController, which you would create yourself
"500"(controller: "error", action: "custom")
You can configure this for any HTTP response status. See the URL Mappings documentation. If you need finer control over different exceptions that might be encountered, look at the "Declarative Error Handling" section in the referenced docs above.
I have a controller that needs to return a 404 page and status code on certain conditions. I can't seem to find out how to do this in Grails. A coworker recommended this method:
response.sendError(HttpServletResponse.SC_NOT_FOUND)
which works perfectly fine, but it's not very Grails-like. I know Rails' render method take a status argument, but Grails' render has no such functionality. Is there something I'm missing, what's the best way to accomplish this?
Setting the response status with its own statement is good enough. It doesn't look too ugly and is pretty straightforward:
response.status = 404;
I've used this successfully myself and have seen others do it this way too. Since it's just a setter, you can also do other stuff after setting the status. Whichever status you set last will be what the HttpServletResponse uses when it actually sends the response back to the client.
I don't know what version this started in, but in Grails 2.2.1 you can do:
render(status: 503, text: 'Failed to do stuff.')
http://grails.org/doc/2.2.1/ref/Controllers/render.html
response.sendError(404) will work with Grails UrlMappings whereas response.status = 404 does not for some reason. This is useful if you want to render a custom 404 error page, as opposed to just sending 404 back to the browser.
response.sendError and response.setStatus are the only two ways I know of. If you static import HttpServletResponse, then it's not that 'un-grails-like'.
Suppose I have a method in my controller that is called via a jQuery AJAX call. E.g. I'd like to delete a user. When everything goes fine, I return new Content('ok') and exit the method.
What should I do when an error occured? I'd like to indicate it by an appropriate status code, so that my error call back would be called called. Why status code? Read here:
How do you trigger the "error" callback in a jQuery AJAX call using ASP.NET MVC?
However, the approach doesn't work because IIS7 returns it's own message (Bad request) insted of my custom error message.
Besides that there are two other catches:
It has to work with IIS6 as well
IE8 doesn't return the 'Bad request' string. Inside error callback the property request.responseTest is null.
The error callback could look like this:
error: function(request) { alert(request.responseText);}
Setting the Response.StatusCode is the correct thing to do. To fix IIS's "helpful" error handling, set the HttpResponse.TrySkipIisCustomErrors property. You can read more about this here.