PHP Try Catch for Entire Class
Asked Answered
C

2

17

Simple question but can't seem to find the answer.

If I have a php class, is it possible to register an exception handler for the whole class?

The reason I want to do this is that my class uses objects that are part of my domain model. These object's methods throw very explicit exceptions. I don't want these exceptions to bubble up to higher level classes, but instead want to catch all these exceptions and throw them as a more general exception e.g. DomainLayerException

I would therefore like one area in my class that catches any number of a list of exceptions I define from my domain model, and throws them as a more general exception e.g.

Currently the way I do this is by wrapping method calls to the domain objects in a try catch block. This is getting very messy as I use more and more domain objects and their methods. Would be great to remove these try catch blocks and handle them all on one place in the class i.e. if any exception is thrown in the class, it is caught by a single event handler defined in the class

Chiquitachirico answered 3/7, 2014 at 11:32 Comment(0)
P
18

You could use a proxy class to perform the calls on your behalf and let you wrap the exception:

class GenericProxy
{
    private $obj;
    private $handler;

    public function __construct($target, callable $exceptionHandler = null)
    {
        $this->obj = $target;
        $this->handler = $exceptionHandler;
    }

    public function __call($method, $arguments)
    {
        try {
            return call_user_func_array([$this->obj, $method], $arguments);
        } catch (Exception $e) {
            // catch all
            if ($this->handler) {
                throw call_user_func($this->handler, $e);
            } else {
                throw $e;
            }
        }
    }
}

$proxy = new GenericProxy($something, function(Exception $e) {
    return new MyCoolException($e->getMessage(), $e->getCode(), $e);
});
echo $proxy->whatever_method($foo, $bar);

It uses the __call() magic method to intercept and forward method calls to the target.

Picard answered 3/7, 2014 at 12:56 Comment(0)
Q
0

EDIT : It seems as this is a bad idea, as "set_exception_handler is a global method. Could end up in a whole world of trouble if lots of classes are setting themselves as the global handler". Thanks to @Gaz_Edge for pointing it out.

You should instead look at Jack's answer.


If i understood what you wanted, i think you can use set_exception_handler in your class.

Example :

class myClass {
    public function __construct() {
        set_exception_handler(array('myClass','exception_handler'));
    }

    public function test(){
        $mySecondClass = new mySecondClass();
    }

    public static function exception_handler($e) {
        print "Exception caught in myClass: ". $e->getMessage() ."\n";
    }
}

class mySecondClass{
    public function __construct() {
        throw new Exception('Exception in mySecondClass');
    }
}

$myClass = new myClass();
$myClass->test();

That would give : Exception caught in myClass: Exception in mySecondClass

Like this, this would output your second Class exception handled by your first Class handler.

Hope it helps !

Quadruped answered 3/7, 2014 at 12:44 Comment(2)
thanks for the answer. Problem with this is set_exception_handler is a global method. Could end up in a whole world of trouble if lots of classes are setting themselves as the global handlerChiquitachirico
@Gaz_Edge absolutely correct not a very good idea to use it like this. Better have the proxy method as described by Jack.Oppugn

© 2022 - 2024 — McMap. All rights reserved.