30

Is there anyway to disable the Laravel error handler all together?

I want to simply display standard PHP errors, not the Whoops, looks like something went wrong errors.

miken32
  • 42,008
  • 16
  • 111
  • 154
Petah
  • 45,477
  • 28
  • 157
  • 213
  • Are you getting no details at all? Laravel uses the "Whoops" library for an error handler so you should see a helpful trace. Demo: http://filp.github.io/whoops/demo/ – Scopey Aug 22 '14 at 02:04
  • 3
    @Scopey no, thats what I am getting, but I don't want that. – Petah Aug 22 '14 at 02:05
  • In 2019 your question implies two different answers at the same time. 1) To disable Laravel error handler while in your PHPUnit test (which is in `app/Exceptions/Handler.php`) you have to use `$this->withoutExceptionHandling()` (see [this answer below](https://stackoverflow.com/a/57521037/6597265)). 2) To get meaningful errors and stack trace instead of `Whoops...` outside tests just put `APP_DEBUG=true` into your `.env` file. – Valentine Shi Aug 23 '19 at 15:40

7 Answers7

46

Not without majorly violating the principles of the framework (which I'll tell you how to do below, if you're still interested).

There's a few things that make this difficult to accomplish. It's easy enough to unset the default error and exception handlers

set_error_handler(null);
set_exception_handler(null);

but that leaves you with two major hurdles.

The first is Laravel registers a shutdown handler as part of its bootstrapping, and this shutdown function will look for the last error, and if it was a fatal error, manually call the exception handling code. There's no easy way to un-register a shutdown function.

The second is, the main Laravel Application handler looks like this

#File: vendor/laravel/framework/src/Illuminate/Foundation/Application.php
public function handle(SymfonyRequest $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
{
    try
    {
        $this->refreshRequest($request = Request::createFromBase($request));

        $this->boot();

        return $this->dispatch($request);
    }
    catch (\Exception $e)
    {
        if ($this->runningUnitTests()) throw $e;

        return $this['exception']->handleException($e);
    }
}

That is -- if you application code throws an exception, Laravel catches it here and manually calls the exception's handleException method (which triggers the standard Laravel exception handling). There's no way to let PHP handle a fatal exception that happens in your application, Laravel blocks that from ever happening.

The part where I tell you how to do what you want

All this means we need to replace the main Laravel application with our own. In bootstrap/start.php, there's the following line

#File: bootstrap/start.php
$app = new Illuminate\Foundation\Application;

Replace it with the following

ini_set('display_errors','1');
class MyApplication extends Illuminate\Foundation\Application
{
    function startExceptionHandling()
    {
        //do nothing
    }

    public function handle(Symfony\Component\HttpFoundation\Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
    {
        $this->refreshRequest($request = Request::createFromBase($request));

        $this->boot();

        return $this->dispatch($request);
    }    
}

$app = new MyApplication;

The first thing we're doing is setting PHP's display errors ini to 1. This makes sure errors are output to the browser.

Next, we're defining a new application class that extends the real application class.

Finally, we replace the real Laravel $app object with an object instantiated by our class.

In our application class itself we blank out startExceptionHandling. This prevents Laravel from setting up custom exception, error, and shutdown callbacks. We also define handle to remove the application boot/dispatch from a try/catch. This is the most fragile part of the process, and may look different depending on your Laravel version.

Final Warnings

If the handle method changes in future version of Laravel this will break.

If custom packages rely on adding custom exception handlers, they may break.

I'd recommend staying away from this as anything other than a temporary debugging technique.

Community
  • 1
  • 1
Alana Storm
  • 164,128
  • 91
  • 395
  • 599
11

Then set 'debug' => false, in \config\local\app.php file

<?php

return array(

    'debug' => false,

);
Komal
  • 2,716
  • 3
  • 24
  • 32
7

In laravel 5 to disable debug, you just need to comment

//'debug' => env('APP_DEBUG'),

in \config\app.php file

rendra
  • 341
  • 4
  • 12
4

Exception handling is hardcoded into the Application class. You can override the classes in your bootstrap/start.php file:

class ExceptionHandler {
    public function handleException($exception) {
        throw $exception;
    }
    public function handleConsole($exception) {
        throw $exception;
    }
}

class MyApplication extends Illuminate\Foundation\Application
{
    public function registerExceptionProvider() {}
    public function startExceptionHandling() {}
}

$app = new MyApplication;

It should go without saying that this is definitely not encouraged.

Andreas
  • 7,991
  • 2
  • 28
  • 37
  • Laravel changing standard error messages is a pretty horrible idea. They don't need to re-invent everything. Some things from stock PHP are good enough. – Goddard Jun 27 '21 at 15:38
1

In file .env, just change:

APP_DEBUG=true

To:

APP_DEBUG=false
rocambille
  • 15,398
  • 12
  • 50
  • 68
0

Related to the question: Laravel has a built in method for disabling exceptions in unit tests:

$this->withoutExceptionHandling()

Laracast on the subject: https://laracasts.com/series/whats-new-in-laravel-5-5/episodes/17

MacroMan
  • 2,335
  • 1
  • 27
  • 36
-1

This will get you close. There might be a more proper way of doing this. It replaces Laravel's current exception handler with a single-method class. I haven't tested this, besides the basic route below, so you may need to add other methods to satisfy different situations.

class ExceptionHandler
{
    public function handleException($e)
    {
        echo $e;
        die;
    }
}

App::bind('exception', App::share(function($app)
{
    return new ExceptionHandler;
}));


Route::get('/', function()
{
    throw new Exception('Testing');
});
kfriend
  • 2,584
  • 1
  • 19
  • 15