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?
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
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();
}
Related
This question already has answers here:
Why do we use finally blocks? [duplicate]
(11 answers)
Closed 3 years ago.
I understand what the "finally" keyword is used for in various languages, however, I struggle to understand why you would use it outside of there being a formatting preference in taste.
For instance, in PHP:
try {
possibleErrorThrownFunction();
}
catch (CustomException $customException) {
// handle custom error
}
catch (Exception $exception) {
// handle the error
}
finally {
// run this code every single time regardless of error or not
}
What's the difference between what this code is doing and this?
try {
possibleErrorThrownFunction();
}
catch (CustomException $customException) {
// handle custom error
}
catch (Exception $exception) {
// handle the error
}
// run this code every single time regardless of error or not
Doesn't that last line always get run anyway due to the error being caught? In which case, there is no case to really use finally unless you just want to maintain a code-style formatting?
An example of a case where a finally statement is necessary and distinct from just putting code after try/catch statements would be helpful if I am missing something here.
Short Answer
Finally blocks are guaranteed to run no matter what happens inside of the try and catch blocks, before allowing the program to crash.
This is sort of explained here: https://www.php.net/manual/en/language.exceptions.php though the explanation isn't particularly detailed.
Some More Detail
One example that comes to the top of my head is if you are dealing with input/output streams or something similar that has to be closed after use in order to avoid a memory leak. To use your example:
try {
memoryUser.startReading(someFileOrSomething);
}
catch (CustomException $customException) {
// handle custom error
}
catch (Exception $exception) {
// handle the error
invisibleBug.whoops(); // i.e. something goes wrong in this block
}
memoryUser.Close(); // because something went wrong in the catch block,
// this never runs, which, in this case, causes a memory leak
In this case, wrapping the memoryUser.Close(); in a finally block would ensure that that line would run before the rest of the program exploded, preventing the memory leak even in an otherwise catastrophic failure.
TL;DR
So a lot of the time, people put the finally block there to ensure an important line runs, even if they overlooked something in the catch blocks. This is how I've always seen it used.
Hopefully this helps :)
What's special about a finally {} block is that it will always run at the end of the try {} block.
It will run if the code in the try {} block completes successfully.
It will run if the code in the try {} block throws an exception that was caught by a catch {}. (The finally {} runs after the catch {}.)
It will run if the code in the try {} block throws an exception that wasn't handled by any catch {} block, or if there weren't any at all. (The finally {} block runs before the exception is propagated to the caller.)
It will run if the code in the try {} block throws an exception, and the code in the catch {} throws another exception (or rethrows the same exception).
It will even run if the code in the try {} block, or in a catch {} block, uses return. (Just as with an uncaught exception, the finally {} runs before the function actually returns.) The finally {} block can even use return itself, and its return value will override the value that the other block tried to return!
(There is one edge case where a finally {} block won't run, and that's if the entire process is destroyed, e.g. by being killed, or by calling exit() or die().)
This probably sounds ridiculous. However, if you don't ask you'll never learn.
I'm relatively new to PHP and self-taught so I haven't exactly learnt everything "to the book".
Is the following required:
try {
}
catch {
}
Am I right in thinking that the try will try to "execute" the code within the brackets and the catch will try and catch the result of the outcome? If there is nothing to catch then it will throw an error?
The first assumption is correct: the code in try will be attempted to run.
However, if no error is thrown, then the block exits normally. If there is an error thrown, then the try execution ends early and goes into the catch block. So your second idea is switched.
try catch is used for exception handling or error handling.Put your script in try block and write your custom error message in catch block.
try{
// put here script
}catch(Exception $error){
//your custom message
echo 'Caught exception: ', $error->getMessage(), "\n";
}
If your script does not execute then it will be jump catch block and access message using $error object.
What is the benefit? The benefit is the whole script will not be stop to execute. It will be continue other block.
In the try block you execute code, whenever something fails in that block it will jump to the catch block. You usually define a variable holding the exception.
So to answer your question, no it will not process the catch block when there is nothing going wrong in the try block. (unless you specifically throw an exception)
try {
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
Try block is hold the code which you want to execute. and Catch block is hold the code if you have cause any error then it will execute the catch code or error message.
Basically try and catch we are using for the error handling and avoid to break the control flow of the program and page.
Simple example:
<?php
class A {
public function getA($a = 0)
{
if ($a === 0) {
throw new ItCantBeZeroException("Message");
}
return $a;
}
}
// I want to throw default exception because I'm not sure
// am I doing it right or what can I do with bad parameter.
$a = new A;
echo $a->getA(0);
// Now, I know what I can do if developer write bad input.
// It can't be 0, so I just print my custom error message
// to my page.
try {
$a = new A;
echo $a->getA(0);
} catch (ItCantBeZeroException $e) {
echo "Parameter can't be zero. Try again.";
}
?>
You can define your own exceptions (like ItCantBeZeroException). Exceptions throw error on site (like "Message") but we can catch them and change to something we want.
You write simple class where some code must be string or integer between 0 and 20.
You use this code, but when user make variable 21, simple class throw error.
You refactor code to catch exception and try to fix code, e.g. change any integer greater than 20 to 20. Then code works properly.
Try and Catch is known as Exception Handling
According to w3schools:
Exceptions Handling are used to change the normal flow of a script if a specified error occurs.
For More:
http://www.w3schools.com/php/php_exception.asp
I don't have the required version of PHP that supports finally, so I am wondering if this:
try {
work();
} catch (Exception $e) {
cleanup();
throw $e;
}
cleanup();
is exactly the same as
try {
work();
} finally {
cleanup();
}
The point of the finally block is to execute regardless of what happens in the try block, or in following catch cases. So if you think about it, the code in the finally block is executed either after a successful try block execution, or after any exception was thrown. So if you write it just as you did in your solution, then you do indeed mimic the situation exactly. If there is no exception, the code after the try/catch structure is executed; and if there is an exception—any exception—you also execute it.
I think the only situation which the finally support may rescue you from, which your version inherently can’t, is when you are actually aborting the outer execution stack early. For example if this code is inside a function and you are returning from within the try block, then the finally would still be executed, but in your manual implementation it of course couldn’t.
So if you make sure that you do not leave early, then yes, it should work in the same way.
There are not many ways to leave a function early that don’t throw an exception; return is the most obvious and aborting the program with exit, die or similar would be another.
Finally code blocks execute always - if there's an exeption, and if there isn't. But if you catch an exeption and do cleanup() after catch block, then yes - it's basically the same thing.
From the PHP docs:
In PHP 5.5 and later, a finally block may also be specified after the catch blocks. Code within the finally block will always be executed after the try and catch blocks, regardless of whether an exception has been thrown, and before normal execution resumes.
If you look at the examples, you'll notice that the finally block will always execute even if the exception is caught. However, when there is an exception, the code will not resume, so the finally block is a good way to ensure that certain lines of code are always executed even if there is an exception.
The finally block will matter if your catch block uses a return function or something like that. Otherwise, there is no difference between putting your cleanup in the finally block or after your try/catch
Here's the example in question from the doc comments:
Just an example why finally blocks are usefull (5.5)
<?php
//without catch
function example() {
try {
//do something that throws an exeption
}
finally {
//this code will be executed even when the exception is executed
}
}
function example2() {
try {
//open sql connection check user as example
if(condition) {
return false;
}
}
finally {
//close the sql connection, this will be executed even if the return is called.
}
}
?>
Generally, yes.
Most of times, both examples work equivalently:
<?php
function work_success() {
echo 'working' . PHP_EOL;
}
function work_fail() {
echo 'working with fail' . PHP_EOL;
throw new Exception('exception');
}
function cleanup() {
echo 'cleanup' . PHP_EOL;
}
Code without finally:
try {
work();
} catch (Exception $e) {
cleanup();
throw $e;
}
cleanup();
Code with finally:
try {
work();
} finally {
cleanup();
}
Results when work = work_success for both finally and non-finally versions:
working
cleanup
Results when work = work_fail for both finally and non-finally versions:
working
cleanup
Exception: exception
However, there are caveats.
Like #poke said, using your examples together with control flow mechanisms might get funny results. Here's an illustration of this using simple return statement:
function test()
{
try {
return 'success';
} catch (Exception $e) {
cleanup();
throw $e;
}
cleanup();
}
echo test();
This will output just success. cleanup() won't get fired unless an exception is thrown. According to prior examples, equivalent finally counterpart to above example would look like this:
function test()
{
try {
return 'success';
} finally {
cleanup();
}
}
echo test();
Note that this will execute cleanup() regardless of any exceptions, so the output will be:
cleanup
success
For some people it's suprising that code in finally block is executed prior to return statements. As long as you are aware of this, there should be no problems.
i've got a try catch in the framework i'm using which when the catch is triggered it displays an error report page, one thing in this report page is that it displays a menu where the times came from the database
what i thought it's do is that i'd put another try catch in the catch in case if the database can be connected to, something like this
try
{
code that would throw an excpetion
}
catch(Exception $e)
{
try
{
connect to database
run query
log error in database
output screen using database data
}
catch(Exception $e)
{
output screen using static html
}
}
this way if the exception was a database connection error it will use a static html output rather than the dynamic one generated from database data
however when i cause a database error (deleting a required table) my static html doesn't work
i am wondering if it is even possible for a try catch to work in the catch or weather it's the framework (i'm using magento), i ask this because if it is possible to be done then i'll spend time figuring out why the framework is stopping me
Yes, it is possible to put a try/catch block in a catch block.
However, from your description, it sounds like you want more 'intelligent' exception catching. You can do something like this:
try {
// some operations including something with a database
}
catch (DatabaseException $e) {
// the exception thrown by the code above was a DatabaseException
// output some error message without using the database
}
catch (Exception $e) {
// the exception thrown by the code above could have been any type of exception EXCEPT a DatabaseException
// so you can still try to use the database to compose the error message
}
Note that anything that can throw exceptions can also throw these exceptions when run from a catch block. For example, when the try block throws an exception before it reaches any database code, a database exception can still occur when handling the original, non-database, exception.
After looking into using try catch blocks for my Pdo statements is it really a benefit? Does this just slow your code down?
I believe that there should be a try catch around the connection command in case the database connection fails. But does there really need to be try catch around each pre prepared statement? These should never change and never really error out.
Any thoughts?
I'm using Php and MySql.
There is no benefit to this:
try {
// exec statement
// exec statement
}
catch (Exception $e) {
// do nothing
}
If you aren't going to do anything with the error and provide a reasonable solution, then you may as well let the exception bubble up to the application's main "something went wrong" error page.
But you may want to do this:
// begin transaction
try {
// exec statement
// exec statement
// commit transaction
}
catch (Exception $e) {
// rollback transaction
// handle error or rethrow $e;
}
And prepared statements can throw exceptions. Perhaps a unique key is violated, or a foreign key constraint is, etc.
But the main point is, you don't use exceptions to hide or silence errors. You use them to catch an error, process it intelligently, and continue on accordingly.