Laravel Exceptions handling when debug=false - laravel

I use the default Laravel Exception handler, but I have a question regarding good practices.
When I have a condition in which the controller must throw an exception, I do the following:
if($blah) {
abort(500, "The user should not be here");
}
and then on the frontend, I have a view that handles the error as this:
#section('message', __($exception->getMessage() ?: 'Whoops, something went wrong on our servers.'))
So that works great as long as I have the following on the .env file:
APP_DEBUG=true
Whenever I change this value to false, (as it should in production), all I get on the error page is: Server Error instead of my custom message.
How can I keep my custom error message, and have APP_DEBUG=false in production?

If you want to customize you HTTP errors for specific views or conditions, then you will have to look into Rendering exceptions section that will show you how to show a custom view for a specific exception. With this you can throw an exception like
throw new UserNotFoundException();
and listen to that exception and render a specific view as required.

Related

Change default Laravel "Server error" message

I've noticed that in production mode with my debug mode set to false that most of my functions that have a try/catch will return the Laravel default "Server error" message.
I've been trying to hunt this message down with little luck, how can I customise this generic message returned from functions within my Laravel app whilst debug is turned off?
If you're referring to a very generic HTTP 500 error, it's a blade file in the framework.
If you want to display your own error for 5XX errors and such, you can override them by creating a blade file with the name of the error you want to override. For example:
resources/views/errors/500.blade.php
{{ __('Uh oh. Something has gone wrong behind the scenes.');
Now when a 500 error is encountered, your blade error will be displayed rather than the default Laravel 500 error.
You can create files for the common errors too obviously.
Update
The default messages for HTTPExceptions in Laravel are provided by the Symfony Response class found in the Symfony\Component\HttpFoundation directory.
When it comes to providing error messages in APIs, most will send the default HTTP status code in the headers and then supply a human error message in the response body.
For your example you might do something like:
return response()->json([
'errors' => [
[
'status' => 500,
'title' => 'Internal server error',
'message' => 'A more detailed error message to show the end user'
],
]
], 500);
You would then be responsible for consuming the error response and showing the end user the human readable error rather than the default generic Internal server error.
You might find some of the JSON API examples useful.
In my case, my Model extends Authenticable.
I changed it to Model and imported Eloquence.

How to debug Laravel app when no error info given at all?

Deployed my Laravel 5.4 app to Heroku and a couple of times I've had the standard "Whoops, looks like something went wrong." exception page with the red banner at the top. Blank white page below that. Nothing in error logs and APP_LOG is set to errorlog and other errors and use of Log::Info() all send to stdout, i.e. Heroku's combined logs and proven to work correctly.
So, just this particular error is generating no info it seems. How to debug this? It's a post to a particular route.
If no logs are being written and the web inspector doesn't give any hints, you can add a dd statement in the app/Exceptions/Handler.php:
public function report(Exception $exception)
{
dd($exception->getMessage());
parent::report($exception);
}
That should print the error message on the page.

Laravel 4: Redirecting when invalid route

I am trying to treat the invalid requests on my Laravel app, something like redirecting to the root will work just fine, but I can't manage to do it.
In the documentation and around stackoverflow I saw this is always the solution:
App::missing(function() {
# handle the error
});
I thought that would just go to the routes file but no. Then I saw in some post it should be in the app/start/global.php file but it still didn't work.
In the docs it says I can "register an error handle". Is that what I should do? What does this mean? What should I do?
Ultimately this can be put anywhere, but app/start/global.php is probably the best place for it.
App::missing(function($exception)
{
return Response::view('errors.missing', array(), 404);
});
Try putting this in there. In fact, if you've just setup a fresh installation, you should already have one there.
Here is how you can register an error handler, like so;
App::error(function(Exception $exception, $code)
{
//Now you can check for different exceptions and handle each on their own way.
}
This will be for PHP general Exception class which will make all exceptions go here, but you can change Exception to the specific Exception class of you own and handle it accordingly.
App::missing will generally be called when a page within your site has not been found, allowing you to show a default page for when users have found a non existing page. So if you are wanting to handle missing pages, use App::missing else use App::error.

ZF2 Session Validators

I implemented the HttpUserAgent and RemoteAddr validators in Zend Framework 2 to help prevent session hijacking.
use Zend\Session\Validator\HttpUserAgent;
use Zend\Session\SessionManager;
$manager = new SessionManager();
$manager->getValidatorChain()->attach('session.validate', array(new HttpUserAgent(), 'isValid'));
It does seem to stop hijacked sessions however, it doesn't let me display a nice error message or reroute the user to the login page, Instead I get this PHP Error message:
Fatal error: Uncaught exception 'Zend\Session\Exception\RuntimeException'
with message 'Session validation failed' in \zendframework\library\Zend\Session\SessionManager.php on line 111.
Is there a callback or something else that I'm not doing to prevent the code from just dying?
This is php we don't use callbacks, but throw exceptions. You need to catch the exception and handle it from there on out.
I would recommend using the event manager and listening on the dispatch event to validate the user.

MVC default redirect Error page doesn't always show

I have a custom error page in my MVC application that's just ~/error/ but when I turn Custom Errors on in the Web.Config like so:
<customErrors mode="On" defaultRedirect="~/error/" />
It only works for 400 errors not server-side 500 errors and instead gives me the following error message on a white page:
"Sorry, an error occurred while processing your request."
How can I just make every single error go to the defaultRedirect page?
500 errors should be handled by the MVC application itself. Custom Errors defined by the web.config are for errors other than 500 errors.
Basically, you need to use the RegisterGlobalFilter method (in global.asax) to add a new HandleErrorAttribute to the filter collection (you'll name the view to use for errors in the HandleErrorAttribute), then create a view that takes as its model System.Web.Mvc.HandleErrorInfo. There is no controller that handles these errors or sends the model to the view, so you can't just redirect to your error page.
You can get more information at http://community.codesmithtools.com/CodeSmith_Community/b/tdupont/archive/2011/03/01/error-handling-and-customerrors-and-mvc3-oh-my.aspx.
EDIT There is an alternative method, where all errors are handled through MVC, shown in How do I display custom error pages in Asp.Net Mvc 3?. Basically, you set up a protected void Application_Error()in your global.asax file to handle all errors, without going through web.config.

Resources