Exceptions: redirect or render? - exception

I'm trying to standardize the way I handle exceptions in my web application (homemade framework) but I'm not certain of the "correct" way to handle various situations. I'm wondering if there is a best practice from UI/ user-friendly point of view.
User logs into application and opens two tabs showing the same screen. On one tab they issue a delete command on object FOO. Then, in the other tab they then click the edit command on FOO (which no longer exists); e.g. a GET request for editObject.php?object_id=FOO. What should I do when they issue the edit request for this nonexistent object?
-Currently I am redirecting these "missing" objects to the previous page with an error message like "object does not exist".
User issues a GET request to search for Objects with color=Red, e.g. searchObjects.php?color=Red. The query returning these results blew up because somebody dropped the OBJECTS table. This is an unexpected exception and isn't quite the same as 1).
-Currently I am redirecting to errorPage.php with a message "Unexpected error"
In general, what should I do if GET/POST parameters that should be there are instead mysteriously missing. Perhaps somebody is trying to inject something?
-Currently I am treating these the same as 2)
What should I be doing in each of the above 3 cases?
Render a "Object does not exist" view at the url editObject.php?object_id=FOO
Redirect to a controller that displays an error view: header('Location: errorPage.php')
Serve a 404: not sure of the syntax for doing this in PHP/Apache
Other

I'd say render it and serve a 404. That way, the user has the chance to see where they went wrong in the URL, or copy & paste it. If you redirect to a generic error page, they don't have that chance.
The PHP way to serve a 404 is
header("HTTP/1.0 404 not found");

Related

call and render a controller method in laravel without a redirect

Background
laravel currently allows you to easily define views for specific HTTP status code responses. For example, an HTTP status code of 404 will display the resources/views/errors/404.blade.php view automatically if it exists. it works the same for other codes like 500 errors.
Problem
All of the routes on my site are processed through controllers, all of which extend a base Controller. This base controller sometimes initializes the user, sets the current timezone, and other random stuff. The master template often relies on these variables. For example, if a user is logged in, the Controller figures that out and passes that user to the view. My master template looks for that user, and shows certain functionality if present. When a 404 is hit, I want to still be able to show the user specific menus, and continue using that 404 view.
Question
I submitted an issue on Github to see if we could route HTTP exceptions through controllers, but they did not agree with the proposal. So now I'm looking to see if there is a way to render a controller method when I catch an HTTP exception. I do not want to simply redirect to the appropriate route, but rather catch the exception and render the controller method.
I don't know enough about the internals of the routing, so I'm curious, is this possible? And if so, how do I do it?
Thanks!
It's definitely possible - look into the ExceptionHandler (under app\Exceptions), or look at implementing some Middleware to catch unknown routes.
Alternatively you can also extend the 404 view from your base template, save data in the session to present on the view or even call a ->back() on the 404 with a flash error.

HTTP errors, can I return data other than HTML?

I want to confirm that I can return an image or a CSS file when I generate a 403 error.
From the documentation, it sounds like I can, as per: any included representation from section 6.5.
6.5. Client Error 4xx
The 4xx (Client Error) class of status code indicates that the client
seems to have erred. Except when responding to a HEAD request, the
server SHOULD send a representation containing an explanation of the
error situation, and whether it is a temporary or permanent
condition. These status codes are applicable to any request method.
User agents SHOULD display any included representation to the user.
Source: https://www.rfc-editor.org/rfc/rfc7231#section-6.5
Would you agree that we do not have to return HTML on a 403 error?
Yes, it's perfectly fine to return something else than HTML for an error.
Image hosts sometimes return errors as images so they would show up when embedded with <img>. Web APIs will often return an error description as JSON/XML. So it's not only perfectly fine, but also common.

symfony2 exceptions - don't return HTML

I've got a symfony2 bundle where I use jquery terminal project. It's a simple javascript console where the user passes some instructions which are executed on server side with AJAX/JSON and returned to the console and displayed. The php server scripts reads the browser-terminal request from $GLOBALS['HTTP_RAW_POST_DATA'].
Currently, when any request throws an error, symfony2 returns a whole HTML response. I don't want the HTML part (I'd like to display the exception message/code only).
The problem is: symfony2 handles exceptions and catches them somewhere, embedding in HTML and returns such response. I want to modify this - the exc. may be caught, but I want no HTML included. There is one distinct bundle, made only for the console stuff.
In fact, the problem was that there was exit statement missing in the controller. The controller response was empty, so an exception was thrown, that a controller has to return a response. After adding exit; after echoing the output, the problem was gone.

REST/JSON/MVC Return Values

Not a great title but I'm looking more for some guidance, have searched quite a bit. I'm building a web app with an MVC framework (but I think this is a more generic question). I'm trying to make many views that do a lot of AJAX style calls and say I have a site with users and they can add folders and files to their profile page. So the URL maybe like:
/profile/{id}
I have a Profile controller that returns a view with various information. I'd like files and folders listed on the profile to be dynamic so I want to populate it through AJAX calls. I was thinking I would have a URL like
/listFolders/{userId}
and
/listFiles/{folderId}
Is it reasonable to have these URLs return a JSON object for these two URLs and not even provide an HTML view (since, for the browser, the view will just be the whole profile page)? Also, what should I return for errors, say if the user/folder doesn't exist or the current logged in user doesn't have access the data? Is it reasonable to just set 404 or 403 HTTP error codes or do they need to return some kind of HTML? What if there are multiple reasons for it to fail and I'd like to pass that along? Should I arbitrarily choose HTTP error codes or define integer return codes like 0, 1, 2, etc? Also, should the URL specify that they are JSON, like listFoldersJSON instead of listFolders?
I have used JSON in my previous projects. For errors, we return error codes.
We decided to do so because we were dealing with API clients. So we want to deal with error codes (REST is based on HTTP, so it was appropriate to return error codes).
Since you are writing your own application, you can pretty much choose how you want to send your errors to the view. You can create a error json object and in the view you have to check whether this object is not null.
pretty much a if-else in the view. Else you can return error codes and check for the code before rendering the JSON into whatever view you want to.
I would go with error codes, because that complies with the REST philosophy.
Generally speaking, I handle this situation by throwing a 500 internal server error with a status message. Most client libraries such as jQuery provide built in error handling with a failure callback like:
jQuery.ajax({
success:function(response){
//do some success stuff
},
error:function (xhr, ajaxOptions, thrownError){
//handle error
alert(xhr.responseText);
}
});
It's entirely feasible to return JSON objects as opposed to actual views.
As far as the url, you can use listFolders and listFiles without taking on the JSON. However, I recommend you use lower case urls for the sake of how the server is setup. For instance, I know on Apache that sometimes listFiles would be fine, but listfiles would lead to missing page exception.
With regards to errors: You could setup a header of sorts in your JSON response and use whatever system you'd like. For instance, you could do something like
status_code: 0 //where 0 means successful
status_detail:success!
Where, if the status_code is something other than 0, you'd check the status_detail and know to ignore everything else inside the response.
Also, what should I return for errors, say if the user/folder doesn't exist or the current logged in user doesn't have access the data?
These are basic HTTP Error codes:
401 : Unauthorized
404 : Not found
There's a whole slew of error messages in the HTTP spec:
HTTP Status Code Definitions
Also, should the URL specify that they are JSON, like listFoldersJSON instead of listFolders?
Generally, a good way to handle this is for the client to set the 'accepts' header to something like 'text/json' or 'text/xml' and for the server to parse it out and respond with the correct response. This way you can use the same URL but send back different views of the data (if you ever wanted)

Should I throw a 404 to a request like /photo.php?id=123 if photo #123 does not exist?

The script will be called from a URL like example.com/photo.php?id=123 or example.com/photos/123 depending on if the have the pretty URLs featured enabled.
If photo #123 does not exist, a request to example.com/photos/123 should throw a 404 error. But, what about example.com/photo.php?id=123?
The relevant RFC is 2616, specifically the sections on status codes, requests, and URIs. Specifically, the query string is considered part of the URI, so a 404 is the proper response since it means:
The server has not found anything
matching the Request-URI.
If you can know that a photo has been permanently deleted, you may return 410.
I would not return 200 and say "no results found."
You should treat both ...?id=123 and .../123 URLs the same, cause they are equal - they just have a little bit different form.
And yes, you should throw an 404 - Not Found error cause given resource doesn't exists. However 404 pages shouldn't never look like:
404 Not found - you're ##$##$#!
404 for URL like ...photo.php should contain a list of suggested resources (different photos that user might wanted to visit), some kind of search form - in other words: it should be a page that allows me to do something rather that just throw error message.
That depends, I suppose.
If photo.php?id=123 is a page showing the photo with an id of 123, then yes, it should throw a 404. 404 means that a resource was not find when it was expected to be found - this is semantically correct.
However, on the odd chance that your semantic intent for photo.php?id=123 was for it to be a page searching for a photo with the id of 123, then it's perfectly correct to return 200 with a message saying that no results were returned.
Ultimately, it doesn't make a huge amount of difference. I'm not very well acquainted with how HTTP response codes affect the way search engines index your page, but I suspect that 404's will not get indexed in the same way. You probably don't want the page being indexed if there's nothing to display.
TL;DR I would throw 404.
Yes, you should throw a 404 if it has never existed:
The server has not found anything matching the Request-URI. No indication is given of whether the condition is temporary or permanent.
But if it has existed before, you should respond a 410:
The requested resource is no longer available at the server and no forwarding address is know
From Status Code Definitions
I think you should throw the 404. This you can easily make using a .htaccess file,
Hope that helps,