Search code examples
phpsilexmonolog

Get access to silex $app in custom Exception constructor?


I would like to use set of custom Exception classes in my project based on silex (silex.sensiolabs.org) framework. I prefer to write an error message into log file in function "__construct". Is there a way to access to $app['monolog'] inside __construct function of MyException class? I think what to use an $app as constructor parameter or as global variable is not elegant way.

class MyException extends Exception
{
    public function __construct($message = '')
    {
        parent::__construct($message);
        //how to do?
        $app['monolog']->addError($message);
    }
}

Solution

  • If you really wanted to, you could have your Exceptions created by the service container (Pimple):

    class MyException extends Exception
    {
        public function __construct($message = '', $monolog)
        {
            parent::__construct($message);
            $monolog->addError($message);
        }
    }
    
    // no share() => create new instance every time
    $app['my_exception'] = function ($app) {
        return new MyException($app['monolog']);
    };
    

    It'd strongly advise against this, you don't want to couple your exceptions to logging logic. A way better approach would be to add an error handler that logs it.

    Example:

    $app->get('/error', function () {
        throw new MyException('A totally expected error happened.');
    });
    
    $app->error(function ($e) use ($app) {
        if ($e instanceof MyException) {
            $app['monolog']->addError($message);
        }
    });
    

    If an error handler does not return anything, the other error handlers will be called until one returns.

    Note: In case you didn't know, the monolog service provider already logs all exceptions.