2

we usually set the message at instantiation, like this:

throw new Exception($msg);`

but I am in a situation where I have a default exception object stored in an instance variable and use it through out the objects lifetime, something like this:

throw $this->my_exception;

Since I am reusing the same object, I need to be able to set message at any time before throwning the exception, you see?

3
  • 2
    Why on earth does it work like that? If you reuse the Exception then the line number maybe wrong as you've already thrown it? What is wrong with throwing a new one? Commented Jan 20, 2011 at 14:12
  • If I may ask: What do you do that for? Commented Jan 20, 2011 at 14:13
  • @jakenoble: client code needs to be able to inject an exception object of his/her preference; i know this sounds strange but i need it... Commented Jan 20, 2011 at 14:24

2 Answers 2

6

Create a custom exception:

class MyException extends Exception
{
    public function setMessage($message) {
        $this->message = $message;
    }
}

And then you can create and throw this exception

$this->exception = new MyException;
// ...
$this->exception->setMessage('Bad stuff happened');
throw $this->expection;

Though I honestly don't get why you would ever do something like that.

Sign up to request clarification or add additional context in comments.

1 Comment

@jakenoble: There are times where it's useful to prepend an exception message with a string to identify which logical block the exception occurred: $e->setMessage(sprintf('Cannot enqueue work: %s', $e->getMessage));. So if you have multiple throws in the same block that affect 'enqueuing work', it makes debugging a tad easier, giving the exception context without having to add the same prefix to all the exception messages.
4

Don't do that. It makes tracing the exception harder (since the stacktrace won't include the re-throw). Instead, if you're using 5.3+ use the $previous parameter and make a new exception:

throw new Exception("message", 0, $this->my_exception);

Even if you're using less than 5.3, you can extend the exception class and add it...

Edit: Ok, based on your comments, I see what you're trying to do now. You want to make your class throw a configurable exception. What I would do, is take a string class name in and store that. So $this->my_exception would be a string. You should verify that it's an exception class before storing it since you can't throw something that doesn't extend from Exception:

if (!is_subclass_of($this->my_exception, 'Exception')) {
    //Error out, since you can't throw that class name
}

Then, when it's time to throw:

$class = $this->my_exception;
throw new $class("MyMessage");

It's still not great since exceptions are supposed to have semantic meaning (hence the existence of LogicException and InvalidArgumentException), but if it's a requirement, that's not a horrible way of doing it (but pre-instantiating an exception is a horrible way of doing it)...

6 Comments

I think that he doesn't rethrow. He simple create the Exception without throwing it and throws it lateron.
@nikic: That's even worse... @Fabio: Why are you doing that? Abusing Exceptions is a very bad idea. Use them properly and only for exceptional circumstances. There's no real reason to instantiate an exception prior to throwing it (or at least not instantiating with the direct intention of throwing). They are not cheap, so don't use them unless you need to...
@ircmaxell: I think so too. I can't think of a situation there creating an Exception before time has any benefit...
what about doing $exception = get_class($this->my_exception); throw new $exception($msg); is this bad?
@ircmaxell: thank you so much, that was it! i was stuck with having to pass an exception object and was doing it that way in order to take advantage of type hinting, but since you can check if a given name is a subtype of the exception class... my problem is solved now ;)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.