Reputation: 48450
I have a simple class in a PHP project that uses something like the following in its constructor:
@set_exception_handler(array($this, 'exception_handler'));
The problem is, it's catching exceptions in global scope, eg: exceptions that are completely not related to the class at all.
Is it possible to limit the scope of exceptions here that are only thrown by instances of this class and/or a specific exception subclass, eg: MyClassException
?
Upvotes: 2
Views: 1369
Reputation: 42915
As said in my comment above you cannot somehow limit a global exception handler to specific exception types or events.
You can however use phps magical __call()
method to achieve something similar without having to use normal try...catch
blocks in all class methods. Consider this simple example:
<?php
class myException extends Exception {}
class myClass
{
public function __call($funcName, $funcArgs)
{
try {
if (method_exists($this, '_'.$funcName)) {
$this->_myFunction($funcArgs);
}
} catch (myException $e) {
var_dump($e->getMessage());
}
}
public function _myFunction($args)
{
throw new myException('Ooops');
}
}
$myObj = new myClass;
$myObj->myFunction();
The output here obviously will be:
string(5) "Ooops"
There are three things to point out here:
_myFunction()
do not have to implement a try...catch
blockA huge disadvantage with such setup is however, that IDEs fail to support such method chains, so you get no auto completion and no signature help for object methods.
Upvotes: 0
Reputation: 3178
You can not set exception handler only for own exception. All handlers work in global scope. But, you can create a own exception handler chain and control all exception.
<?php
interface ExceptionHandlerInterface
{
public function supports(\Exception $e);
public function handle(\Exception $e);
}
class ExceptionHandler implements ExceptionHandlerInterface
{
public function supports(\Exception $e)
{
return $e instanceof \Exception;
}
public function handle(\Exception $e)
{
throw $e;
}
}
class MyExceptionHandler implements ExceptionHandlerInterface
{
public function supports(\Exception $e)
{
return $e instanceof MyException;
}
public function handle(\Exception $e)
{
exit("Oops, this is a my exception.\n");
}
}
class ExceptionHandlerChain
{
private $handlers;
public function addHandler(ExceptionHandlerInterface $handler, $priority)
{
// you should sort all handlers with priority
$this->handlers[] = $handler;
}
public function handle(\Exception $e)
{
foreach ($this->handlers as $handler) {
if ($handler->supports($e)) {
$handler->handle($e);
}
}
}
}
class MyException extends \Exception
{
}
$chain = new ExceptionHandlerChain();
$chain->addHandler(new MyExceptionHandler(), 0);
$chain->addHandler(new ExceptionHandler(), 1024);
set_exception_handler([$chain, 'handle']);
//throw new RuntimeException();
throw new MyException();
Upvotes: 2