MightyPork
MightyPork

Reputation: 18861

Php selective exception handling

I have a problem where I want to catch all exception except descendants of my custom exception.

Maybe bad design, but here it is (Simplified and names changed, but the code is quite accurate):

function doStuff()
{
    try {
        // code
        if (something) {
            // manually throw an exception
            throw StuffError("Something is bad.");
        }

        // a third-party code, can throw exceptions
        LibraryClass::arcaneMagic();

    } catch (Exception $e) {
        throw new StuffError("Error occured while doing stuff: "
             . $e->getMessage());
    }
}

/** My custom exception */
class StuffError extends Exception
{
    function __construct($msg) {
        parent::__construct('StuffError: ' . $msg);
    }
}

However, the issue here is that I don't want the try-catch to intercept the manually throws StuffError. Or, seamlessly rethrow it or something.

As it is now, I'd get:

StuffError: Error occured while doing stuff: StuffError: Something is bad.

I want just:

StuffError: Something is bad.

How would I do it?

Upvotes: 0

Views: 83

Answers (2)

cHao
cHao

Reputation: 86505

You can have multiple catch clauses, and the first one that matches will be the one that runs. So you could have something like this:

try {
    do_some_stuff();
}
catch (StuffError $e) {
    throw $e;
}
catch (Exception $e) {
    throw new StuffError(Error occurred while doing stuff: " . $e->getMessage());
}

But you might want to rethink wrapping stuff like this. It obscures the real cause of the error. For one thing, you lose the stack trace. But it also complicates error handling, since now someone can't differentiate exception types the way you're trying to do, short of trying to parse the exception message (which is rather an anti-pattern in itself).

Upvotes: 2

The Maniac
The Maniac

Reputation: 2626

I might be misinterpreting you, but I think this is what you're looking for:

    ...

} catch (Exception $e) {
    if (get_class($e) == 'StuffError' || is_subclass_of($e, 'StuffError')) {
        throw $e;
    } else {
        throw new StuffError("Error occured while doing stuff: "
             . $e->getMessage());
    }
}

    ...

Replace your catch statement with the code above. It checks to see if the exception is a StuffError or a child class of StuffError. I'm still very confused at why you would need to throw a StuffError exception after you catch, but maybe that's just some weirdness coming from translating/cleaning your code.

Upvotes: 0

Related Questions