lara9849's avatar

I liked Whoops, this new "thing" does not appease me. It's just a bog standard stack trace, the old one allowed me to step though using the sidebar where i could see the executed code and identify problems with ease. Now i need to manually trawl though the files looking for the code that was executed which isn't a problem but feel Whoops was miles better and aided in debugging much faster than the replacement.

I have since added Whoops! back, because it suits my workflow better.

pgnonick's avatar

@bart Hi bart, i tried your solution, but nothing changed. I created a new service provider and i registered it in the app config. Finally i started php artisan dump-autoload. But there is the standard stack trace of Laravel 5. Did I forget something?

1 like
bart's avatar

I think it's these three steps:

1. Add the package
2. Create the ErrorServiceProvider
3. Execure composer dump-autoload

You can try something dd() to check if the provider is loaded. Another possibility are code changes from during the last past days in the laravel/laravel package.

pgnonick's avatar

Mh, there must be changes in the core... ServiceProvider is loaded

minuwan's avatar

@bart , @pgnonick is right. At the moment it's not working as expected. Even dump-autoload doesen't seem to override the symfony error stack.

codedungeon's avatar

@bart seems this no longer works with latest Laravel 5 install (installed today and Whoops no long works). Any chance you have tried with latest build? Does it work for you?

pgnonick's avatar

Here is my solution:

1.) Add in the composer.json "filp/whoops": "~1.0"

2.) Create in your app folder a "Infrastructure" folder. Then create a ExceptionHandler.php in this folder with following code:

<?php namespace App\Infrastructure;

use Exception;
use Illuminate\Http\Response;
use Psr\Log\LoggerInterface;
use Illuminate\Contracts\Debug\ExceptionHandler as ExceptionHandlerContract;

class ExceptionHandler implements ExceptionHandlerContract {

    /**
     * The log implementation.
     *
     * @var \Psr\Log\LoggerInterface
     */
    protected $log;

    /**
     * Create a new exception handler instance.
     *
     * @param \Psr\Log\LoggerInterface $log
     * @return void
     */
    public function __construct(LoggerInterface $log) {

        $this->log = $log;

    }

    /**
     * Report or log an exception.
     *
     * @param \Exception $e
     * @return void
     */
    public function report(Exception $e) {

        $this->log->error((string) $e);

    }

    /**
     * Render an exception into a response.
     *
     * @param \Illuminate\Http\Request $request
     * @param \Exception $e
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function render($request, Exception $e) {

        $whoops = new \Whoops\Run;
        $whoops->pushHandler(new \Whoops\Handler\PrettyPageHandler());

        return new Response($whoops->handleException($e), $e->getStatusCode(), $e->getHeaders());

    }

    /**
     * Render an exception to the console.
     *
     * @param \Symfony\Component\Console\Output\OutputInterface $output
     * @param \Exception $e
     * @return void
     */
    public function renderForConsole($output, Exception $e) {

        $output->writeln((string) $e);

    }

}

3.) Open up bootstrap/app.php change this:

$app->singleton(
 'Illuminate\Contracts\Debug\ExceptionHandler',
 'Illuminate\Foundation\Debug\ExceptionHandler'
);

to this:

$app->singleton(
 'Illuminate\Contracts\Debug\ExceptionHandler',
 'App\Infrastructure\ExceptionHandler',
 'Illuminate\Foundation\Debug\ExceptionHandler'
);

Now you can customize your Exception Handler.

@Milon521 Thanks for your hint to the commit

2 likes
bart's avatar

I think I will wait until official documentation has been updated. Maybe in final release this will be damn simple. So in my opinion it will change several times until then. It's alpha folks :)

xian13's avatar

Solution from @pgnonick works well, but i prefer to extend from the Illuminate Exception Handler to remove the code repetition because i just want to override the render function.

Here is my tweak from @pgnonick snippet :

<?php namespace App\Infrastructure;

use Exception;
use \Illuminate\Contracts\Config\Repository as Configuration;
use Psr\Log\LoggerInterface;
use Illuminate\Http\Response;
use Illuminate\Foundation\Debug\ExceptionHandler as BaseExceptionHandler;

class ExceptionHandler extends BaseExceptionHandler {

 /**
  * Create a new exception handler instance.
  *
  * @param \Illuminate\Contracts\Config\Repository $config
  * @param \Psr\Log\LoggerInterface $log
  * @return void
  */
 public function __construct(Configuration $config, LoggerInterface $log)
 {
       parent::__construct($config, $log);
 }

 /**
  * Render an exception into a response.
  *
  * @param \Illuminate\Http\Request $request
  * @param \Exception $e
  * @return \Symfony\Component\HttpFoundation\Response
  */
 public function render($request, Exception $e)
 {
       $whoops = new \Whoops\Run;
       $whoops->pushHandler(new \Whoops\Handler\PrettyPageHandler());

       return new Response($whoops->handleException($e), $e->getStatusCode(), $e->getHeaders());

 }

}
2 likes
psmail's avatar

I think I heard Taylor give the reason Whoops has been left out on the live podcast earlier today. Stuffed if I can remember what that reason was though.

codedungeon's avatar

@psmail There has to be a good reason? Maybe it will return when it goes final since the framework is still in flux, thus so is implementation of Whoops....

I am just going to wait it out... The current Sympony error report is more than adequate at the moment.

codedungeon's avatar

@pgnonick Tried you solution and it worked perfectly... Now we will see how long this lasts before a future update breaks it ;-)

psmail's avatar

@codedungeon. No. I am saying there is a reason - Taylor's own words as per a recent live podcast. I just can't remember it.

MrSimonBennett's avatar

The reason is whoops does not use the HTTPKernal and handles the returning of a error to the client differently.

Whoops its self can be error prone and many times I have had white screens of death caused by Whoops.

Kostik's avatar

Did Taylor try to debug code in ajax query with Symphony Debuger ? In Firebug for ajax log i see a lot of HTML code wich wrapp php Exception. Strange solution to remove Whoops then.

Kostik's avatar

for ajax debug use next code

    public function render($request, Exception $e) {

        $whoops = new \Whoops\Run;

        if ($request->ajax())
        {
            $whoops->pushHandler(new \Whoops\Handler\JsonResponseHandler());
        }
        else
        {
            $whoops->pushHandler(new \Whoops\Handler\PrettyPageHandler());
        }

        return new Response($whoops->handleException($e), $e->getStatusCode(), $e->getHeaders());
    }
willvincent's avatar

This gets whoops working with the most recent dev repo and the smallest amount of additional code, including Kostik's suggestion for handling ajax requests.

Add a file WhoopsHandler.php to app/Exceptions with the contents:

<?php namespace App\Exceptions;

use Exception;
use Illuminate\Http\Response;
use App\Exceptions\Handler as BaseExceptionHandler;

class WhoopsHandler extends BaseExceptionHandler {

    /**
     * Render an exception into a response.
     *
     * @param \Illuminate\Http\Request $request
     * @param \Exception $e
     * @return \Symfony\Component\HttpFoundation\Response
     */
     public function render($request, Exception $e) {
        $whoops = new \Whoops\Run;

        if ($request->ajax())
        {
            $whoops->pushHandler(new \Whoops\Handler\JsonResponseHandler());
        }
        else
        {
            $whoops->pushHandler(new \Whoops\Handler\PrettyPageHandler());
        }

        return new Response($whoops->handleException($e), $e->getStatusCode(), $e->getHeaders());
    }
}

Note, by extending the default exception handler the only thing that needs to be overridden is the render function.

Then update bootstrap/app.php like so:

$app->singleton(
        'Illuminate\Contracts\Debug\ExceptionHandler',
        'App\Exceptions\WhoopsHandler',
        'App\Exceptions\Handler'
);
3 likes
andy's avatar

Life without this is just .... white screen of death when you have blade errors.

Thank you all for putting this together!

Speaking of which, has anybody put this to a package yet?

michaeldyrynda's avatar

Laravel doesn't execute the blade files, they're compiled, and the compiled PHP is what is executed. Whoops always showed the error in the compiled file, not the source template.

jabba's avatar

@deringer - in L5 yes, but in L4 no.

Example from L4 app:

Next exception 'ErrorException' with message 'Call to undefined method Illuminate\Database\Query\Builder::getUsers() (View: C:\xampp\htdocs\demoapp\app\views\start\hello.blade.php)' in C:\xampp\htdocs\demoapp\vendor\laravel\framework\src\Illuminate\Database\Query\Builder.php:2170

(i made a typo: correct method is getUser(), but i renamed it to getUsers() in hello.blade.php)

michaeldyrynda's avatar

@jabba - my bad! That may also be a by-product of the way that L5 now renders views. Even with whoops, it is still showing the error in the compiled view, not the blade file (unless the stack trace shows the blade file).

cbrown's avatar

@bart the color scheme that the code that you have provided is displaying in , with the dark background, yellow, blue and green txt ? up at the very top of this page , your code is formatte in these colors .

Please or to participate in this conversation.