1

Ok, I understand the "accepted answer" that was given for this question, but it's still not clear to me what kind of code should I put in finally blocks.

If the use of finally is to get the non-catched exceptions thrown and give a general error message for the system not explode for the user, wouldn't appear two error messages for the user if some exception was catched?

[Edit]

Like @MarkBaker said, the "finally" isn't for catch the uncaught exceptions, the generic catch(Exception $e) do that. So... for what it's useful? Or, in other words, what the finally block does that I can't do after the try/catch blocks without finally?

Community
  • 1
  • 1
Rafael Barros
  • 1,043
  • 18
  • 25
  • 4
    The use of `finally` isn't `to get the non-catched exceptions thrown and give a general error message`, you use a general `catch(Exception $e)` for that.... `finally` is for code that is common whether an exception is caught or not (e.g. closing file handles) – Mark Baker Sep 16 '13 at 15:52
  • 1
    I don't know if there's a PHP specific answer or if try/catch/finally best-practices can be used. http://stackoverflow.com/questions/1158667/why-use-finally-in-try-catch – Mike B Sep 16 '13 at 15:52
  • @MikeB - I think that maybe the "accepted answer" of the link that you put would solve the problem when the man said that even if the try/catch blocks exits or throw another exception, the finally would execute, and that would be the difference, because all the rest of the code wouldn't, but I tried here and, if I exit or throw another exception inside the try or catch block, the finally and the rest of the code (anything after these blocks) had the same behavior. – Rafael Barros Sep 16 '13 at 16:42
  • @MarkBaker - I don't see how a general catch(Exception $e) could get the uncaught exceptions. I have to create catch blocks with the exactly same name that the exception class thrown, and if I can foresee an "throw new Exception" and can foresee "throw new AnyException", resulting in none uncaught exceptions, ever. – Rafael Barros Sep 16 '13 at 17:10
  • 1
    Your catch blocks needn't be "exact name": Exceptions have an extension hierarchy, and as all Extensions extend `Exception` as the great granddaddy of them all then `catch(Exception $e)` will catch any exceptions that aren't explicitly caught by other explicit exception class names in catches. If I have 3 different child exceptions that all extend PDO_Exception, then a `catch(PDO_Exception $e)` will catch any of those three – Mark Baker Sep 16 '13 at 17:34
  • Hmm, ok, understood now. Another doubt persists, so I will change the question. – Rafael Barros Sep 16 '13 at 19:35

2 Answers2

1

Maybe the following explanation will better help you understand how it works:

try {
    function1();//this might throw an exception
    function2();//if we want function2 to be executed regardless 
                //if an exception was thrown from function1() - this 
                //is not a good place to call it!
} catch (Exception $e) {
    echo $e->getMessage();
} finally {
    function2();//then the right place to write it will be in a finally clause.
}

When an exception is thrown from function1() - function2() will not be executed - the execution will "jump" to the catch section. If we want function2() to be executed regardless if an error was thrown, for example, if function1() opens a connection to the DB and runs some selects and function2() closes that connection, then we'd better place the call to function2() in the finally block that follows the catch

Nir Alfasi
  • 53,191
  • 11
  • 86
  • 129
  • The function2() will execute even if didn't exist a finally block and if it was after the try/catch blocks. The only way it wouldn't is if the function1() throws an exception not by the "Exception" class (an uncaught exception). That's the point: what kind of code I would want to execute in this case. – Rafael Barros Sep 16 '13 at 16:51
  • 1
    @RafaelBarros not necessarily: what about the scenario where another exception is being thrown from inside the `catch` clause ? ;) – Nir Alfasi Sep 16 '13 at 16:58
  • If I am understanding the scenario correctly, the same behavior happens, like I said to @MikeB in the comments section from my question. Ps: I've tried. – Rafael Barros Sep 16 '13 at 19:41
  • @RafaelBarros I didn't understand your last comment. Further, changing the question is not recommended cause it invalidates all the answers that were posted and were valid! better place a new question. – Nir Alfasi Sep 16 '13 at 19:46
  • Hmm, I am new on the best practices of the StackExchange, but I think this could happen after I edit the question, so, I didn't edit literally, I added a new one. If you think this can confuse future viewers, I can edit again and open a hole new question. About my last comment, in short words: same behavior if I add a new throw (I tested). – Rafael Barros Sep 16 '13 at 19:59
  • @RafaelBarros I already answered that question on the first comment here – Nir Alfasi Sep 16 '13 at 20:37
  • 1
    @RafaelBarros if another exception is thrown from the code which is executed inside the catch clause, then the code that you'll write after the catch will not be executed unless it's inside `finally`. Try it! – Nir Alfasi Sep 16 '13 at 22:08
  • Yep! I can see that now, i did another test and it worked. The hole problem is that i was making tests in a manner that couldn't possibly work anyway. I will create a answer that i think can't leave any doubts, instead of mark yours as the "accepted", but know that was you that push me to think and try others things. – Rafael Barros Sep 17 '13 at 14:44
  • @RafaelBarros I'm glad to hear that it worked out - good luck! :) – Nir Alfasi Sep 17 '13 at 17:07
  • Oh dude, my own answer was wrong and i see that now. You were right from the beginning. I deleted mine and accepted yours. Thank you again! – Rafael Barros Oct 08 '13 at 14:07
0

The 'finally' block should hold code you want executed regardless of the outcome of the try/catch block. For example, if you try to query a database and catch the error, you would still likely want to close the database connection, regardless of whether the database operation succeeded or not. See below:

open_database_conn();
try{
  query_database();
  return_result();
}
catch(Exception $e){
  echo $e->getMessage();
}
finally{
  close_database_conn();
}
JRP
  • 979
  • 6
  • 9