views:

232

answers:

4

If you use a custom error handler in PHP, you can see the context of an error (the value of all variables at the place where it occurred). Is there any way to do this for exceptions? I mean getting the context, not setting an exception handler.

A: 

The equivalent function for handling eceptions is:
set_exception_handler()

Another very useful function is:
debug_backtrace()

Peter Lindqvist
Yes, but that's not my question. I need to get the context from an exception that I've already caught. Thanks for your time though
Bart van Heukelom
By default PHP exceptions don't contain that information, and by the time you have caught the exception, the info about local vars etc. that you want has already been destroyed because the originating stack frame has already been popped. If you don't have control of the context where the exception was thrown so you can add the context there, then there's no way for you to get that context.
Nate C-K
+1  A: 

You can attach the context to your exception manually. I have never tried it, but it would be interesting to create a custom exception that in the constructor calls and saves get_defined_vars() for later retrieval.
This will be a heavy exception :-)

proof of concept:

class MyException extends Exception()  {
    protected $throwState;

    function __construct()   {
        $this->throwState = get_defined_vars();
        parent::__construct();
    }

    function getState()   {
        return $this->throwState;
    }
}

even better:

class MyException extends Exception implements IStatefullException()  {
    protected $throwState;

    function __construct()   {
        $this->throwState = get_defined_vars();
        parent::__construct();
    }

    function getState()   {
        return $this->throwState;
    }

    function setState($state)   {
        $this->throwState = $state;
        return $this;
    }
}

interface  IStatefullException { function getState(); 
      function setState(array $state); }


$exception = new MyException();
throw $exception->setState(get_defined_vars());
Exception e
Hmm, but get_defined_vars here will not include local variables from the code that constructs the exception, right?
Bart van Heukelom
Not if they are invisible to the `Exception` indeed. To overcome this I would recommend to add a method `setState(array $state)` and supply `get_defined_vars` when you throw the exception. I changed the code accordingly.
Exception e
+1  A: 

Exceptions in PHP:

http://www.php.net/manual/en/language.exceptions.extending.php

Methods of the basic Exception class:

final public  function getMessage();        // message of exception
final public  function getCode();           // code of exception
final public  function getFile();           // source filename
final public  function getLine();           // source line
final public  function getTrace();          // an array of the backtrace()
final public  function getPrevious();       // previous exception
final public  function getTraceAsString();  // formatted string of trace

So, this is what you have to work with if you caught a basic exception. If you don't have control over the code that generates the exception then there's not much to be done about getting any more context as the context in which it was thrown is gone by the time you catch it. If you are generating the exception yourself then you can attach the context to the exception before it's thrown.

Nate C-K
A: 

Couldn't you also do:

class ContextException extends Exception {

    public $context;

    public function __construct($message = null, $code = 0, Exception $previous = null, $context=null) {
        parent::__construct($message, $code, $previous);
        $this->context = $context;
    }

    public function getContext() {
        return $this->context;
    }
}

That would avoid the need to instantiate the exception and then throw it.

Andrew