13

Suppose to have a PHP code inside a try...catch block. Suppose that inside catch you would like to do something (i.e. sending email) that could potentially fail and throw a new exception.

try {
    // something bad happens
    throw new Exception('Exception 1');
}
catch(Exception $e) {
    // something bad happens also here
    throw new Exception('Exception 2');
}

What is the correct (best) way to handle exceptions inside catch block?

Giorgio
  • 1,940
  • 5
  • 39
  • 64
  • 4
    never thought about this but maybe you can nest a try-catch block inside the parent catch? – gbestard Aug 26 '14 at 12:49
  • 1
    It all depends: can your application finish its job if an exception is thrown? If so, then usually, the exception is logged, and a notice is added to the response/output. If the app can't continue (ie: a critical db connection fails, the app fails), then the exception is either not caught (messy), or _is_ caught, logged and an error response is returned (status 500, 404, 301/302 redirect etc...) – Elias Van Ootegem Aug 26 '14 at 12:51
  • @gbestard: yes, this could be a solution. My question was only to know if there's a common (best) practice for this case. Thanks! – Giorgio Aug 26 '14 at 12:52
  • @EliasVanOotegem: my case is actually what I've mentioned in example. I have an error inside try block and I would like to notify it with an email to administrator. But email code may fail and throw a new exception. My actual solution is to "mute" email exceptions and go on without sending email, but I suppose there's something better of this. – Giorgio Aug 26 '14 at 12:58
  • Write it to a log file. – sridesmet Aug 26 '14 at 13:01
  • 1
    @Giorgio: code that throws a specific exception does a specific job. That kind of code shouldn't be in the same try-catch block as other code: `$db = new PDO();` throws a `PDOException`, if you want to catch those, you wrap that line in a try-catch. Nothing else. If a specific method can throw different exceptions, and you want to handle them differently, you can write `try{} catch (MinorException $e){}catch(Exception $e){//all other exceptions}` – Elias Van Ootegem Aug 26 '14 at 13:20

4 Answers4

11

Based on this answer, it seems to be perfectly valid to nest try/catch blocks, like this:

try {
   // Dangerous operation
} catch (Exception $e) {
   try {
      // Send notification email of failure
   } catch (Exception $e) {
      // Ouch, email failed too
   }
}
Community
  • 1
  • 1
Simon East
  • 55,742
  • 17
  • 139
  • 133
1

You should not throw anything in catch. If you do so, than you can omit this inner layer of try-catch and catch exception in outer layer of try-catch and process that exception there.

for example:

try {
    function(){
        try {
            function(){
                try {
                    function (){}
                } catch {
                    throw new Exception("newInner");
                }
            }
        } catch {
            throw new Exception("new");
        }
    }
} catch (Exception $e) {
    echo $e;
}

can be replaced to

try {
    function(){
        function(){
            function (){
                throw new Exception("newInner");
            }
        }
    }
} catch (Exception $e) {
    echo $e;
}
Justinas
  • 41,402
  • 5
  • 66
  • 96
  • I'm not sure how it can be adapted to my case. In my situation I have a function inside try and a function inside catch. Both can throw exceptions. At the moment, I'm able to handle exceptions thrown inside try, but not those thrown inside catch. Anyway, if the best practice is to avoid exceptions inside catch, I'll find a way to "mute" them. – Giorgio Aug 26 '14 at 13:18
  • @Giorgio Just wrap try-catch block top most level of your code, lets say where all executions begins (in frameworks it would be index.php) – Justinas Aug 26 '14 at 13:23
1

You have 2 possible ways:

  1. You exit the program (if it is severe) and you write it to a log file and inform the user.
  2. If the error is specifically from your current class/function, you throw another error, inside the catch block.
sridesmet
  • 875
  • 9
  • 19
  • I'm not sure to have correctly understood your answer... I suppose that if you want to exit the program / throw another error, you should have a way to "catch" it, right? So, you were wondering something like @gbestard suggested in his comment? – Giorgio Aug 26 '14 at 13:03
  • No. If the error is so severe your program can't continue, or if the error has nothing to do with that class/function, then you exit the program and write it to a log file. If the error has something to do with that class/function, you throw an error in the catch-block. – sridesmet Aug 26 '14 at 13:06
  • Ok, this is clear but my problem is that I may have something that throws an exception inside catch block and I don't know how to catch it. You're talking about the handling of the error, but my problem is that I'm not able to catch this error. If you run my current snippet, you'll get a fatal error saying there's an uncaught exception. This is why I was asking how to catch it. – Giorgio Aug 26 '14 at 13:13
  • You could document the fatal error in your question. – sridesmet Aug 26 '14 at 13:16
  • 1
    You probably have to catch your exception in the calling method, that'll make the error disappear. See http://stackoverflow.com/questions/9350976/uncaught-exception-in-try-catch-block But honestly, if it's your email problem, I'd write it to a log file and not throw another error. – sridesmet Aug 26 '14 at 13:18
0

You can use finally. Code in this branch will be executed even if exception is thrown within catch branch

  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Mar 07 '22 at 20:46