1

I'm using the Yii 2 framework and it uses a number of extended exceptions and I'm having an issue with them where I threw a UserException but it ended up being caught by the base Exception but I'm not sure why!?

The code:

try {

    //........

    if ($reader->count() > 0) {     

        if (!$already_active) {         
            //.....
        } else {
            throw new UserException('You have already activated your account; you may continue to login.');             
        }

    }

} catch (\Exception $e) {

    // User exception above is caught in here?

} catch (UserException $e) {

    // Rethrow the exception
    throw $e;

}

Shouldn't the User Exception be passed onto and caught by the second catch?

2 Answers 2

5

From http://php.net/manual/en/language.exceptions.php

When an exception is thrown, code following the statement will not be executed, and PHP will attempt to find the first matching catch block.

The catch block for Exception will be executed since Exception is a parent of UserException and therefore any object of type UserException is also of type Exception.

Therefore you should refactor your code to have the catch block for child classes first. In your case UserException should be first.

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

6 Comments

+ 1, You're answer looks great buddy, But I think that there will be no difference if we put UserException in first. No?
Oh ok, I thought it would be caught by the "matching" exception type; didn't know Exception was a catch-all; thought that's why the finally was added in PHP 5.5 for.
I disagree. The exception handler uses instanceof to match the exception thrown and executes the code in the first catch which matches. In this case UserException matches both catch blocks so it is just a matter of which comes first. For more information look at tuxradar.com/practicalphp/19/8/7
umm, you're totally right, but, I just tested it right now, there was no difference :D
@AliMasudianPour check the example in this answer. I have tested it and the results are correct.
|
2

If you take a look at UserException class you can see:

class UserException extends Exception

Therefore, Exception has the higher priority.

However you can do just:

//if something's wrong
throw new \yii\base\UserException('You have already activated your account; you may continue to login.');

2 Comments

I use this at the top use yii\base\UserException; so I can just reference it as UserException :)
@Brett :)) Thanks buddy, there is no difference at all.

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.