Using Try/catch with Do/While - php

this is more of a conceptual question.
Is it aceptable/good programming mixing do/while loops with try/catch?
ex:
<?php
function main() {
$failure = 0;
do {
$failure += foo();
$failure += bar();
...
if ($failure) { return $failure; }
}
while ($failure == 0);
}
function foo() {
try {
echo 'DO FOO STUFF<br />';
return 0;
}
catch (Exception $e) {
return 1;
}
}
function bar() {
try {
echo 'DO BAR STUFF<br />';
return 0;
}
catch (Exception $e) {
return 1;
}
}
?>
The reason I'm asking is that I read somewhere that mixing both is bad practice. You should create your own exceptions and "throw" them instead. But isn't that a bit of an overkill?
EDIT:
To explain the scenario where this question emerged, imagine a robot that has to follow a line. The robot calculates its position (X position, Y poistion, Z position and "postural" position) everytime he takes a step and sends the information to a server. Server doublechecks this information. If any anomaly is found, servers sends a "stop" signal to the robot. The robot stops, recalculates its position, resends information and waits for a "go" signal.
This loop example was based on the data feed received from the robot. If something went wrong, (like a broken wireless link, or an obstacle, or a misstep) the robot must stop to prevent going astray, or falling, or anything. We aren't interested in knowing what went wrong, or why it went wrong, just that it went wrong (or not). (that is actually taken care in another part of the code, not PHP based, the Debug Module).
EDIT 2:
Like everyone pointed out, seems the right approach is to properly raise/handle the exceptions.
Since everyone seems to agree in this, I don't know who to award the "right answer" tick.
I will wait a few days and give it to the one with more votes if that's ok!

There is no reason to avoid mixing try/catch with do/while.
But the example you give has less problems with do/while and more with swallowing exceptions in the try/catch block.
Catching the base exception type and swallowing it is a bad practice in any language, PHP or otherwise. It is best to only catch specific exception types, and let the rest fall through the catch block.
For example, if you were accessing a file, and caught the FileNotFound exception (if there is such a thing in PHP), that would be OK.
But if you catch all exception types, then you're going to catch things like OutOfMemoryException. This would be fine, if you properly handled it, and made sure it wasn't going to throw again. But in your case, you're probably not "doing the right thing" for that case, so you should just let it fall through.
The reason you don't want to eat exceptions (without logging them) is that you won't be able to debug your code if it ever goes to a locked down production environment. If the exception is caught, then the user will just see buggy behavior, and won't be able to file a bug report that gives you enough information to debug it. They might be able to give you repro steps, but that is pretty unreliable. This is also pretty much worthless for an intermittant problem.
If you eat the exception, you're basically throwing away the most useful data there is for debugging.
Things that make this less true:
Sometimes in top-level web code, you will want to catch the exception, log it, then swallow it so the user doesn't see it (but return from the function, so you don't execute more code while in a buggy state). This makes it so the user doesn't see revealing information about your code (the stack trace).
If the language you are doing exception handling in has poor support for exceptions, and doesn't have derived exception types. I don't know a lot about PHP, so this may or may not be true in this language.

If you want to swallow the exceptions and just report the failure then this is okay. You'll have to do something like
$failure &= bar();
though, or you'll lose the failure condition of foo().
If you want to be able to act on the exception further up the call stack then you're better off leaving it alone, or at least rethrowing it, so you can catch it where you want to handle it.

There is no general reason to avoid using try/catch within functions called inside a do/while loop.
Depending upon what you are actually doing inside the loop you have the option of catching exceptions inside the loop, and exiting on an error condition returned, or wrapping the whole while loop in a try/catch block.
You should decide how to do it in any specific case according to what the exceptions mean for your code:
Can the exception be recovered from?
What action needs to be taken in response to an exception being thrown?
What state should your program be left in after a particular exception has been thrown and handled?
In your example, bar() will be executed even if foo() generates an error. This may or may not be what you want. Catching exceptions outside the loop would not allow this option.
Also, the loop won't terminate when bar() returns false if foo() subsequently returns true - this is probably a bug. Catching any exceptions outside the loop would mean the loop would be terminated at the point of error. Again, this may or may not be desirable depending on your application.
Also, it is likely that different exceptions need to be handled in different ways. Importantly, if you catch the base exception type, rather than a more specific derived type you are losing the ability to do this. Catching more specific exceptions (including custom exceptions) will help you:
Make sure you are not
accidentally swallowing unexpected
exceptions you didn't mean to catch.
Have multiple different error
scenarios handled by the same catch
block (by throwing the same custom
exception for each of those error
scenarios).

Related

understanding exceptions

I have read articles upon articles trying to understand what exceptions are used for in php and I have gone through the answers already given in the forum. One of the answers which made atleast some sense to me is this one: Are exceptions in php really that useful?
Here is a simple function for finding the inverse of a integer with and without using exceptions (source):
With exception:
function inverse($x) {
if ($x==0) {
throw new Exception('Division by zero.');
} else {
return 1/$x;
}
}
try {
inverse();
}
catch (Exception $e) {
echo $e->getMessage();
}
Without exception:
function inverse($x) {
if ($x==0) {
echo "I'm zero. Don't let me be the denominator.";
} else {
return 1/$x;
}
}
So here is my question, why and when should I use one over the other?
why and when should i use one over the other?
Oh, this is easy: You should never use "without exception" :) Don't misuse return values as status flag. Thats a bad habit from earlier days and only makes things more complicated, because then you have to check the return values and even their types over and over again.
If you have a function like inverse() the only thing it should ever do is to "inverse". If it can't do it, it's an exceptional situation, thus (you may guess) an exception.
To sum it up: Throw an exception, when there is a situation, that prevent a function/method to work properly, and that the function/method is not able to handle itself.
There are various opinions on "when to use an exception". My personal opinion is:
If you are working with your own code, theres basically no need to throw exceptions, as you then need to write your own handler for it - which also can be done without throwing an exception.
If you are developing APIs that other programmers are using, it can be usefull to throw exceptions, so the developer using your code knows, that he has to take care of handling errors, AND gets an idea of what was the error-reason. (instead of just getting null he might catch NumberToSmallException, NotANumberException, ....)
In other words: When you already know how to handle an exception if it would appear - dont throw it. If the handling should be up to another developer, using your code - throw it.
Exceptions should not be used to control the flow of your application logic. Therefore use if / else statements.
But these are just my ten cents.
Especially when you use object oriented programming, exceptions are quite handy. For example, in an application where you use a DB library that throws exceptions for when it cannot make a connection. In that case, you can catch that exception somewhere, and you show a special page that tells the user that the database is not working.
Maybe the best usage of Exceptions happens when there a method calls more than one level.
Think like I call method A, then it calls method B, and it calls method C. When this happens, if you do not use exceptions, method A must know all different types of error messages of method B. And method B must know about C's in the same way. But by using exception, method C's error can be caught easily without the help of method A and B.
Exceptions should be used when your script encounters an error, in the example you can't divide by zero and so you have a logical error, so an exception would be appropriate.
Using exceptions allows you to see better errors messages and will help when it comes to debugging, rather than simply printing out a string which could be anything. Furthermore you can catch exceptions so you can detect when something goes wrong, whereas simply outputting a string isn't of much help.
Check out the PHP docs on this for more info.
Exceptions are an invaluable tool when writing complex and/or extensible pieces of software, but saying that return values aren't good for reporting anomalies is IMHO an oversimplified and even dogmatic approach.
In this specific case it's perfectly reasonable to return a null value, as in "the inverse of the argument does not exist". For me the most important point is that inverse does not actually do anything; it merely provides some information (i.e. it is "read-only", it has absolutely no side effects).
Note that "absolutely no side effects" is also a good rule of thumb which means that you should definitely not echo from within the function unless echoing is why it exists in the first place.
If there were an expectation that after calling inverse successfully the state of the program would have changed and inverse cannot perform this change for whatever reason (perhaps it got passed bad arguments; perhaps a resource it needs is not available; etc) then you should absolutely throw an exception and let the caller decide how to handle the error.
Think of it like this:
Sometimes, the value for $x comes from a user (eg. from an HTML form or something), in this case you would like to display an error (maybe something like "The frobing level needs to be different than zero").
Other times, you are getting the value from a database, in that case it's kind of useless to tell the user about frobing levels or stuff like that, you will want to show an error page and log detailed information somewhere on the server (or even send an email to an admin).
With the second example it's not really possible to control what happens in case of an error (the same message is printed each time).
The right thing to do is to let the code that is calling your function decide what happens in case of an error. Exceptions are one way of doing this.
There are 2 major benefits of using exceptions:
They go through the execution stack (meaning that if you have a few nested functions, you don't have to re-pass the error value, this is done automatically.
The first piece of code after a throw() statement is the code in a catch() statement. This means that you don't have to make hundreds of checks in every nested function/method you have.
Considering this functionality, using a return value is useful in simple cases (for example your case). In complex cases, where you have 10-20-30 different error messages that can appear in different levels in the execution stack, using exceptions is a must, or other developers(/even you in a few months) will have major problems when debugging.
That's my 2 cents on the issue, hope it helps.
PS: It's useful to log the exceptions in an exceptions.log.

Why should I use exception handling in php?

I've been programming PHP for a long time, but not so much PHP 5... I've known about exception handling in PHP 5 for some time, but never really looked into it. After a quick Google it seems fairly pointless to use exception handling - I can't see the advantages of using it over just using some if() {} statements, and perhaps my own error handling class or whatever.
There's got to be a bunch of good reasons for using it (I guess?!) otherwise it wouldn't have been put into the language (probably). Can anyone tell me of some good benefits it has over just using a bunch of if statements or a switch statement or something?
Exceptions allow you to distinguish between different types of errors, and is also great for routing. For example...
class Application
{
public function run()
{
try {
// Start her up!!
} catch (Exception $e) {
// If Ajax request, send back status and message
if ($this->getRequest()->isAjax()) {
return Application_Json::encode(array(
'status' => 'error',
'msg' => $e->getMessage());
}
// ...otherwise, just throw error
throw $e;
}
}
}
The thrown exception can then be handled by a custom error handler.
Since PHP is a loosely typed language, you might need to ensure that only strings are passed as arguments to a class method. For example...
class StringsOnly
{
public function onlyPassStringToThisMethod($string)
{
if (!is_string($string)) {
throw new InvalidArgumentException('$string is definitely not a string');
}
// Cool string manipulation...
return $this;
}
}
...or if you need to handle different types of exceptions in different ways.
class DifferentExceptionsForDifferentFolks
{
public function catchMeIfYouCan()
{
try {
$this->flyForFree();
} catch (CantFlyForFreeException $e) {
$this->alertAuthorities();
return 'Sorry, you can\'t fly for free dude. It just don\'t work that way!';
} catch (DbException $e) {
// Get DB debug info
$this->logDbDebugInfo();
return 'Could not access database. What did you mess up this time?';
} catch (Exception $e) {
$this->logMiscException($e);
return 'I catch all exceptions for which you did not account!';
}
}
}
If using transactions in something like Zend Framework:
class CreditCardController extends Zend_Controller_Action
{
public function buyforgirlfriendAction()
{
try {
$this->getDb()->beginTransaction();
$this->insertGift($giftName, $giftPrice, $giftWowFactor);
$this->getDb()->commit();
} catch (Exception $e) {
// Error encountered, rollback changes
$this->getDb()->rollBack();
// Re-throw exception, allow ErrorController forward
throw $e;
}
}
}
Exception handling: If condition versus Exception isn't specific to PHP, but gives a good perspective. Personally, Exception(s) & try/catch are implemented in languages to enforce good behaviour amongst developers that normally wouldn't be as attentive to error checking / handling.
If you are confident that your if/else if/else is catching all scenarios, than cool.
Here is an overview of the Advantages of Exceptions - Java -- At one point, there is a snippet of code that has many if/else statements and the following excerpt:
There's so much error detection, reporting, and returning here that the original seven lines of code are lost in the clutter. Worse yet, the logical flow of the code has also been lost, thus making it difficult to tell whether the code is doing the right thing: Is the file really being closed if the function fails to allocate enough memory? It's even more difficult to ensure that the code continues to do the right thing when you modify the method three months after writing it. Many programmers solve this problem by simply ignoring it — errors are reported when their programs crash.
So really, it comes down to personal preference in the end. If you want code that is readable and can be consumed by other people, it's generally a better approach and enforces best-behaviour
If you are following the object-oriented methodology then exceptions comes handy for the error handling. It is convenient to communicate the errors through exception across the objects.
Exceptions are really helpful if you go with layered design approach.
If you are not coding in object-oriented way, then exceptions are not required.
We use exception handling if we are not sure about the code results. We put that snippet of code in try block and catch that error in catch block. Please check this link for more information.
In general there are two good reasons to use exception handling:
You might now always know where an exception will occur - something unexpected could arise. If you use a global exception handler you can make sure that no matter what goes wrong, your program has a chance to recover. Similarly a particularly sensitive piece of code (like something that does I/O) could have all sorts of different errors that can only be detected at runtime and you want to catch any possible contingency. Some things might not occur during testing; like what if a server outside of your control fails? This may never be tested before it really happens (although good testing would include this). This is the more important reason really.
Performance. Typically exceptions are implemented so that everything is fast so long as nothing goes wrong. Exceptions are caught after they occur. This means that no 'if' statement has to be evaluated in advance if something goes wrong, and the overhead is very low in that case. If you don't use exceptions you will be forced to add a lot of 'if' statements to your code. While usually this isn't much of a problem, this can kill a performance-critical application. This is especially true because a branch mis-prediction in the CPU can cause a pipeline flush.
I that reason is that Exception is called after trigger_error(); function and you can send also some additional information to that exception = better debugging?
I'm not sure but I think that's it
example:
class db
{
function connect()
{
mysql_Connect("lolcalhost", "root", "pass:)") or trigger_error("Test");
}
}
try
{
}
catch (db
One of the primary reasons for having an exceptions framework is so that if the code ever gets to the point where it cannot proceed, it has the ability to tell the surrounding context that something has gone wrong. It means that if I have a class Foo which needs to have $fooInstance->setBarHandler($barHandler) called before $fooInstance->doFoo(); can succeed, the class can provide a message to the greater context instead of failing silently and returning FALSE. Further, it allows the context to say, "Huh. That broke. Well, I can now tell the user/logs/something else that something bad happened, and I can decide whether I need to keep on chugging."
Exceptions can provide much more data than simple -1 or false.
Exceptions can do advanced error handling. Keep in mind that try .. catch blocks can be nested and there could be more than one catch block in try .. catch block.
Exceptions force you to handle errors. When you're not using them you do something like:
function doSomething($a, $b, $c) {
...
if ($a < $b && $b > $c) {
return -1; // error
}
...
}
$d = doSomething($x, $y, $z);
if ($d === -1) {
die('Fatal error!');
}
And everything is fine as long as you remember to check whether function returned error. But what happen if you forgot to check that? It's actually a quite common problem.
Exceptions make the flow of a program much more natural.
Exceptions are hard to use in the correct context,especially in php. Personally i use exceptions when these 3 things happen:
Resource failure exception - You can throw an exception maybe when your program runs out of memory. for example in php when you run a script that exceeds 30 seconds executing. Though you can chanage that in .ini
Client code errors exceptions - For example when trying to connect to a database with the wrong credentials or unlinking a file not on server. Or when the database server is down and unresponsive, you can throw an exception.
Programmer error exception - These are errors generated due to your own coding problems.This can also be used when you are not sure of the results your code will give you. for example when dividing by 0.

Are exceptions in php really that useful?

3 days ago I started rewriting one of my scripts in OOP using classes as a practice after reading a lot about the advantages of using OOP.
Now I'm confused weather I should use exceptions or not. They seem to make my work harder and longer.
My application check if the data was sent through an Ajax request or not then uses that info through the script.
Check this example :
/*
* The older way
*/
if($ajaxEnabled) {
$error = errorWrap('Ajax error');
} else {
$error = errorWithBackLinkWrap('NoAjax error');
}
function doSomething() {
if(empty($POST['name'])) {
die($error);
}
}
/*
* OOP way
*/
class someClass {
private $_ajaxEnabled;
public function doSomething() {
try {
if(!$this->_isDateValid()) {
if($this->$_ajaxEnabled) {
throw new ajaxException('Ajax error');
} else {
throw new noAjaxException('NOAjaxError');
}
}
} catch(ajaxException $e) {
echo $e->getErrorMessage();
} catch(noAjaxException $e) {
echo $e->getErrorMessage();
}
}
}
This code is only for demonstrating the problem, so I know there are some undefined functions in it :).
So before going oop, error handling was easier for me because I only had to echo the appropriate error.
Now using exceptions, in every function I have to check the type of connection first then write 2 catch functions for each thrown exception, which lead to a much larger code.
I'm really new to OOP in php so maybe there is a cleaner and a better way to do this, is there ?
Your question is not uncommon, whether/when to use exception is sometimes a philosophical decision and many experienced developers can't wrap their heads around it.
That being said, I've found that listing out the distinct properties of each way of handling error makes it easy to choose your preferred way:
Return code
The caller can ignore it or forget to check it
The caller usually needs more documentation reading before he can use it (does 0 mean success or failure?)
Object destruction is not guaranteed -- it all depends on the caller to clean up properly
When to use: It's pretty obvious. Use return codes when you trust the caller (internal code or trivial errors which can be safely ignored).
Exceptions
The caller cannot ignore it
The caller can still suppress it if he wants (with an empty try/catch)
Object destruction takes places properly -- most of the time
When to use: When you don't trust your caller as much (third party) or you really need to make sure your error code doesn't go ignored.
Die
Cannot be ignored and cannot be suppressed
When to use: It's usually obvious enough. You need everything to stop immediately.
(In a PHP context, I don't think it makes much difference. The above suggestions should still apply.)
(Aside)
Usually it's tempting to just write out an error message when something bad happens (especially when the first programming language you learned is PHP :P). But if you really want to grok OOP, it's not a proper way to handle errors.
Every object or every function should ideally only perform one function. If one function writes error to the screen and does its own thing, it's difficult to later switch to a DatabaseErrorLogger or TextFileErrorLogger or etc. One approach would be to supply a logger to use (this is called Dependency Injection). Another way to do it is to use exception -- this way, the caller gets to choose which ErrorLogger to use.
Exceptions as an error handling mechanism are VERY different in concept and implementation than function return codes. You cannot/should not simply map one to the other. You should read and digest this article (and then a few more including this one*) before proceeding further.
If you're going to favor exceptions instead of return codes for error reporting/handling then the structure of your code should change significantly.
(*The CodeProject link is .NET-specific but there's little code ti digest. It's mostly a best-practices article easily applicable to any language.)
You shouldn't use exceptions when your code can handle the error gracefully using an if statement (like you did there on your example).
Exceptions are for situation that are well, exceptional. Unfortunately this is not very straightforward, so it's up to you, the programmer, to decide what is exceptional or not. I think a good rule of thumb is:
Avoid using exceptions to indicate
conditions that can reasonably be
expected as part of the typical
functioning of the method.
From: http://www.codeproject.com/KB/dotnet/When_to_use_exceptions.aspx
Exceptions' usefullness is not in printing error codes. It's in catching error so you can try to solve them instead of crashing with fireworks.
If I understand how you're doing it, I think you're doing it wrong. Exceptions for not for errors. They are for exceptional circumstances. Errors can mean any number of things (for example, a user didn't enter a long enough user name on a registration form). That itself shouldn't be an exception. You could however use an exception to show that registration itself failed (Depending on the situation)...
And you don't need to have a try/catch block at every level. In fact, that's bad practice. Only catch exceptions if you either can handle the exception, or need to do something else before letting the exception continue. So, for example: If you are connecting to a remote set of websites, and the first one fails. You can catch the exception for that one, and retry with a second website. And keep going until you have no more left (at which point you'd throw another exception to indicate that no websites could be fetched). Another example would be if you're generating images. You have a method that does some computation while generating the image that throws an exception. You'll want to catch that exception so that you can "clean up" from the image process (to save memory, etc) and then re-throw it once you're done: catch (ImageSomethingException $e) { /* Clean up here */ throw $e; }...
The true power of exceptions is that it lets you handle the situations however you want (since the exception can just bubble up to the top of the program). But only catch exceptions where you know you can deal with them (or at least need to clean up). You should almost never do print $e->getMessage() inside of production code.
Personally, I have a default exception handler that I always install. Basically, if an exception is not caught, it will log that exception and then generate a 500 error page. That lets me focus on what exceptions I can deal with in code instead of trying to catch everything (which isn't usually a great idea)...
Good luck...
I personally hate exceptions. I don't work with them in my applications. I prefer functions returning (and expecting) defined status codes, and dealing with recoverable errors on that level.
In truly exceptional situations (like an unreachable database server, a file I/O error etc.) that are an immediate emergency, I tend to trigger and handle a fatal error. (Object shutdown will still take place, so any connections that need closing etc. will still be handled as long as they are placed in destructor functions.)
Third party libraries' exceptions I strive to catch as quickly as possible, and deal with them in my own way.
Joel Spolsky puts the reasons much better than I could in his notorious Exceptions essay.
Note that this is one view and one school of thought. There is a lot of brilliant software whose error handling is based entirely on exceptions, and that is perfectly fine. The key is consistence - either you make the design decision to use them, or you don't.
There is a finite capacity to most development processes - i.e. even where its possible to predict all possible circumstances that the code might run in (i.e. all possible combinations of inputs, all possible states for supporting systems like database, DNS, existing data etc) then its just not practical to deal with every scenario. Using exceptions allows you:
to bundle a series of operations into one entity for the purposes of determining success/ failure as a whole
handle multiple different modes of failures with a single bit of code
So yes - I'd say that exception handling is a useful practice - but not a substitute for handling the common failure modes specifically, intelligently and informatively (and typed exceptions are IMHO a complete oxymoron).
If all you need is to display error message, why don't you use
catch (Exception $e)
{ print ($e->getMessage()); }
Its a developers call.. not mandatory as kizzx2 told.
But if you are writing up some util or library kind of class its always good to throw exception as this lib or util may be used by others in future.

Is it best practice to try - catch my entire PHP code, or be as specific as possible?

I do not have many kinds of Exceptions in my project.
Right now,(we use MVC) I have the try catch encompassing my entire code:
try{
fronController::dispatch($somthing...);
}catch(Exception $E){
//handle errors
}
I wonder if there is a good reason to use the try-catch block in as specific as possible way as I can or just keep it general as it is now?
The idea of an exception is so that a function can report failure without having to return special values. In ye old PHP, the only way a function could say it had a problem was by returning some special value like false or -1. This is not pleasant. For example, suppose I am writing a variant of file_get_contents().
The typical return value is a handle - represented by a positive integer. However, there are two basic problems I can encounter: the file you specified was not found, or the file you specified was not readable. To indicate an error I might return a negative number - because handles are positive - that associates to the particular cause of error. Let's say that -1 means the file wasn't there and -2 means the file wasn't readable.
Now we have a problem that -1 and -2 do not inherently mean anything to someone reading the code. To rectify this we introduce the global constants FILE_NOT_FOUND and FILE_NOT_READABLE. Let's see some resultant code.
<?php
define('FILE_NOT_FOUND', -1);
define('FILE_NOT_READABLE', -2);
function my_file_get_contents($file) {
// blah blah blah
}
$friendListFile = getDefaultFriendListFile();
$result = my_file_get_contents($friendListFile);
if ($result == FILE_NOT_FOUND) {
deleteFriendListFromMenu();
} elseif ($result == FILE_NOT_READABLE) {
alertUserAboutPermissionProblem();
} else {
useFriendList($result);
}
By having different error codes we can act accordingly to what the problem really is. That functionality is well and fine. The issue is purely in how the code reads.
$result is a horrible variable name. Variable names should be descriptive and obvious, like $friendListFile. The real name for $result is $fileContentsOrErrorCode which is not only too long, it examplifies how we are overloading a single variable with two meanings. You never, ever, want to have the same data mean two things. We want a separate $errorCode and $fileContents!
So how do we get around this problem? One not-really-a-solution some PHP libraries have used is to have their my_file_get_contents()-like functions return false if they encounter a problem. To disambiguate what the problem actually was we instead call my_file_get_contents_getError(). This almost works.
define('FILE_OKAY', 0);
define('FILE_NOT_FOUND', -1);
define('FILE_NOT_READABLE', -2);
$my_file_get_contents_error = FILE_OKAY;
function my_file_get_contents_getError() {
// blah blah blah
}
function my_file_get_contents($file) {
global $my_file_get_contents_error;
// blah blah blah
// whoa, an error? return false and store the error code in
// $my_file_get_contents_error
// no error? set $my_file_get_contents_error to FILE_OKAY
}
$friendListFile = getDefaultFriendListFile();
$result = my_file_get_contents($friendListFile);
if (my_file_get_contents_getError() == FILE_NOT_FOUND) {
deleteFriendListFromMenu();
} elseif (my_file_get_contents_getError() == FILE_NOT_READABLE) {
alertUserAboutPermissionProblem();
} elseif (my_file_get_contents_getError() == FILE_OKAY) {
useFriendList($result);
} else {
die('I have no idea what happened. my_file_get_contents_getError() returns '
. my_file_get_contents_getError()
);
}
As a note, yes, we can do a much better job by avoiding a global variable and other such little bits. Consider this the nuts-and-bolts demonstration.
We still cannot call $result anything better than $fileContentsOrFalseIfError. That problem has not been fixed.
I have now rectified one problem that you may have noticed in the earlier example. What if we do not cover all of the error codes? If a programmer decides that there needs to be a -3 code we weren't originally detecting it! We could have checked if $result was a string to make sure it wasn't an error code, but we aren't supposed to really care about types in PHP, right? Now that we can utilize a second return value from my_file_get_contents_getError() it is no problem to include a success code.
There is now a brand new problem that has emerged. Fix one and find three more eh? The new problem is that only the most-recent error code can be kept. This is terribly fragile! If anything else calls my_file_get_contents() before you deal with your error code, their code will overwrite yours!
Gah, now we need to keep a list of functions that are unsafe to call before you deal with the return value from my_file_get_contents_getError(). If you don't do that, you have to keep as an ad-hoc coding convention that you always call my_file_get_contents_getError() immediately after my_file_get_contents() in order to save the error code that belongs to you before it is mysteriously overwritten.
Wait! Why don't we just hand out identifiers to our callers? In order to use my_file_get_contents() you now have to ask create_my_file_get_contents_handle() for some number that will disambiguate you with all other callers. Now you can call my_file_get_contents($myHandle, $myFile) and the error code can be stored in a special location just for you. Now when you call my_file_get_contents_getError($myHandle) you can access that special place, get your error code, and no one has stepped on your toes.
Er, but if there are many callers we don't want to have zillions of useless error codes laying around. We had better ask users to call destroy_my_file_get_contents_handle($myHandle) when they are done so we can free some memory.
I hope this is all feeling very familiar to ye old PHP mantras.
This is all so crazy, just make it simple, please!
What would it mean if the language supported a better mechanism to react to errors? Clearly, trying to create some solution with the existing tools is confusing, obnoxious, and error-prone.
Enter exceptions!
<?php
class FileNotFoundException extends Exception {}
class FileNotReadableException extends Exception {}
function my_file_get_contents($file) {
if (!is_file($file)) {
throw new FileNotFoundException($file);
} elseif (!is_readable($file)) {
throw new FileNotReadableException($file);
} else {
// blah blah blah
}
}
$friendListFile = getDefaultFriendListFile();
try {
$fileContents = my_file_get_contents($friendListFile);
useFriendList($fileContents);
} catch (FileNotFoundException $e) {
deleteFriendListFromMenu();
} catch (FileNotReadableException $e) {
alertUserAboutPermissionProblem();
}
All of a sudden our old headaches of special return values and handles and coding conventions have been cured!
We can now truly rename $result to $fileContents. If my_file_get_contents() has a problem, the assignment is aborted altogether and we jump right down to the appropriate catch block. Only if there is no error do we even think about giving $fileContents a value or calling useFriendList().
No longer are we plagued by multiple callers stepping on each other's error codes! Every call to my_file_get_contents() will instantiate its own exceptions, if the error arises.
No memory problems! The garbage collector will happily clean up no-longer-used exception objects without you thinking about it. Using ye old handle system we had to remember to manually destroy the handle, lest have it lurk around forever in memory.
There are many other benefits and traits to exceptions. I strongly recommend looking to other sources to learn about these. Particularly interesting are how they bubble up the execution stack until some caller can catch them. Also interesting is how you can catch an exception, try to fix the problem, and then rethrow the exception if you can not. Do not forget that exceptions are objects! There is loads of flexibility to be gained by that. For exceptions that no one can catch, look into the exception handler.
My intent to answer the question was to demonstrate why we need exceptions. By doing this, I hope it is easy to infer what problems we can solve with them.
generally throw locally, catch globally unless an exception handler is specific to a function in which case handle locally.
class fooException extends Exception{}
// DB CLASS
public function Open(){
// open DB connection
...
if ($this->Conn->connect_errno)
throw new fooException("Could not connect: " . $this->Conn->connect_error);
}
// MAIN CLASS
public final function Main(){
try{
// do stuff
}
catch(fooException $ex){
//handle fooExceptions
}
}
Remember that exceptions are for exceptional cases. As I understand that, that happens when the error is out of your control. For example, invalid parameters are passed to a public API function, division by zero, situations like 'network connection lost', 'file not found'... this kind of things.
As a general rule, you should catch the exceptions that you know how to handle, like recovering from the error, log the error and propagate it, etc. If you don't know how to handle it, it's better to let it fail. Otherwise your application could be in an error state that you may not want.
So answering your question, it's better to be as specific as possible since every exception should be handled only if you know what to do with it (silently swallowing is a bad idea). If not just let the exception notify the user that something went wrong. Or if you want to, catch the exception to log the error and rethrow it.
There's good discussion here for C++, but the general concepts apply. I found the java tutorials on exceptions also very good.
You should be as specific as possible with catching errors in your code. Catching specific errors appropriately increases code maintainability, makes your code structured and organized.
It is also good practice as a convention, especially if you later work on team-based projects and you're not the only one looking at the code.
Personally throwing everything into one try catch block seems to be a code smell.
If you are using a try block for all your code, you might as well define a default exception handler (see the docs).
Other than that, the size of the try block is up to you, it depends on how fine you want your error handling to be. If you can't recover from any of the exceptions, there's really no reason to be specific, unless you want to log error messages that are specific (but the message of the exception and the stack trace will probably be enough).
If your handling all of your errors with one general catch you will get minimal feedback and options when an error does occour, it may be fine during development but when its on the front line it could cause you no end of problems.
Be specific and cover all of your bases where feedback is needed and recoverablity is possible.
Different errors may require different responses.
You wouldn't jump out of an airplane in response to every possible problem that could arise. Would you?
Well, that's what your app is doing.
There are situations where an exception can be caught and the application could continue to run. More likely, the app may need to respond to the same class of exception differently in different situations. Perhaps in one function an I/O exception isn't detrimental but in another it is.

What is the advantage of using try {} catch {} versus if {} else {}

I am switching from plain mysql in php to PDO and I have noticed that the common way to test for errors is using a try / catch combination instead of if / else combinations.
What is the advantage of that method, can I use one try / catch block instead of several nested if / else blocks to handle all errors for the different steps (connect, prepare, execute, etc.)?
I'd use the try/catch block when the normal path through the code should proceed without error unless there are truly some exceptional conditions -- like the server being down, your credentials being expired or incorrect. I wouldn't necessarily use it to handle non-exceptional errors -- say like the current user not being in the correct role. That is, when you can reasonably expect and handle an error that is not an exceptional condition, I think you should do your checks.
In the case that you've described -- setting up and performing a query, a try/catch block is an excellent way to handle it as you normally expect the query to succeed. On the other hand, you'll probably want to check that the contents of result are what you expect with control flow logic rather than just attempting to use data that may not be valid for your purpose.
One thing that you want to look out for is sloppy use of try/catch. Try/catch shouldn't be used to protect yourself from bad programming -- the "I don't know what will happen if I do this so I'm going to wrap it in a try/catch and hope for the best" kind of programming. Typically you'll want to restrict the kinds of exceptions you catch to those that are not related to the code itself (server down, bad credentials, etc.) so that you can find and fix errors that are code related (null pointers, etc.).
In general, try-catch blocks are great because they will break (move to the catch statement) whenever the exception occurs. If-else blocks rely on you predicting when the error will happen.
Edit:
Also, catch blocks won't stop your code from halting when an error is hit.
Throwing and catching an exception is an expensive operation compared with most any other primitive operation. If this is a piece of code that needs to perform well (eg, in a tight loop), you will want to look at your use case - if you expect the exceptions to be thrown relatively often, you will be better off with an if/else perforance-wise (unless the underlying code is just wrapping an exception for you, in which case there's no gain at all). If the exceptions are only thrown in rare circumstances, then you're better off with a try/catch to avoid the overhead of branching in a tight loop.
The advantage of try/catch, and exceptions in general, is more for the people developing libraries like PDO. They allow a system developer to handle undefined situations or unexpected results in a quick and easy way. Take a database connection. What should a system do if the database can't be reached. Should it halt execution? Try again? Throw a warning and continue? The system developer can't know what you'll need it to do, they they throw an exception, which you'll later catch and handle.
The advantage for you, as a consumer of the system is rather than getting some vague error code back, or a simple boolean false that it failed, you get an Exception object which will
Be named in such a way that it's more obvious what went wrong (If I remember right, PDO only has one Exception type, but other systems contain multiple exception types for different kinds of errors)
May/should contain methods and properties which can help you figure out why the exception was thrown
That's the theory anyway. There are lots of smart people who claim Exceptions are the way to go. There are also lots of smart people who think Exceptions are the devil, and a crutch for lazy system developers. There is nothing resembling consensus on this issue.
#Perchik:
My general philosophy of error handling:
You should use if / else to handle all cases you expect. You should not use try {} catch {} to handle everything (in most cases) because a useful Exception could be raised and you can learn about the presence of a bug from it. You should use try {} catch {} in situations where you suspect something can/will go wrong and you don't want it to bring down the whole system, like network timeout/file system access problems, files doesn't exist, etc.
Vexing exceptions
Try/Catch totally separates the error handling logic from the object business logic.
That’s exactly the advantage, using one try/catch instead of multiple if statements. You will also be able to catch any unanticipated errors.
Everybody else had good answers - but I figured I would throw my own in:
Try/Catch is an actual exception handling mechanism - so if you change your exceptions, it will automatically work on all try/catch statements.
Try/Catch gives the opportunity to run code even in the case of a major exception that might kill the if/else and in addition, the try statement can be rolled back (if you're savvy).
Since PDO is using objects, they are raising Exceptions if an error occur. The old mysql/mysqli were mere functions and didn't throw Exceptions they simply returned error codes. Try/catch is used when an Exception can be thrown from the code, and you catch it in the catch-clause, which is an object oriented way to handle errors. You can't catch Exceptions with if/else blocks - they share nothing with try/catch.
In php by using Try Catch with inheritence, We can throw exception from another class.
Example :- I am in the controller and validating user data by using Models.
If any error triggers, I just have to throw exception from Model methods.
The execution in try will break and catched in the Catch Block.
So There is less overhead of returning bool vales and checking that.
Apart from this Try Catch works great When using in chain ( Try - Catch inside another Try - Catch ).
This question has been asked more than a decade ago out of the wrong premise. In reality if and try are incomparable matters. Sadly, but up to this day people catastrophically confuse exceptions with try catch, thinking one is inseparable from another.
In the way it is asked, indeed it makes very little sense to change if {} to try {} in the meaning of obligatory try wrapping a single line of code to test for the error.
However the actual question is What is the advantage of using exceptions versus if {} else {}.
And it starts to make a whole world of sense immediately: exceptions allow automated error reporting, when neither try catch nor if else is ever have to be written.
An exception is essentially an automated way to write if ($result == FALSE) raise_error(); Without exceptions you are bound to test every operation's result manually. It would be just stupid to recreate the same behavior using exceptions. In most cases a thrown exception should be left alone, unless there is a certain handling scenario. In all other cases it has to bubble up elsewhere, hence no try {} catch {} has to be written.
Let's say we are writing an a/b division code and the most famous exception case has occurred i.e. 0 divide error, what do you think can be done next?
1. You can print a message and exit.
2. You can print a message and let the user re-enter the values, etc.
There are cases when different people/vendors want to handle the same exception case in different way. The catch block let them do this with ease. If you need to change the way how a certain exception case will be handled, you just need to change the catch block.
TRY/ CATCH can be used within the programming context where you have very little information about the error or you think that might can occur such as.
#include <iostream>
using namespace std;
int main (){
try{
while(true){
new int[100000];
}
}
catch(bad_alloc& e){
cout << e.what() << endl;
}
}
Although there are no semantic or compile-time errors in the program, but it's understandable that it posses a run-time error which is "bad_alloc" which appears when you try to continuously allocate the memory and your program run out of memory. This exception is defined in bad_alloc standard class which is a child-class of class "Exception", since it throws an implicit exception, throw keyword is not implied here.
You can also use try/catch to check if the file is accidentally deleted and can use if/else to check if there exists a file or not, both have their own advantages.
Try and Catch functions are useful whenever there is a communication between functions. In Try and Catch , if there exists an exception in the TRY block, the control is transferred directly to the CATCH block which would store our exception condition. This however is not possible in case of IF ELSE, where in IF condition , if there exists an exception, the control cannot go to the ELSE block howsoever in any case.
int division(int a,int b){
if(b==0)
throw 101;
return a/b;
}
int main()
{
int a=10,b=0,c;
try{
c=division(a,b);
cout<<c<<endl;
}
catch(int a){
cout<<"Division not possible by 0"<<endl;
}
}
Consider the following Code: throw and catch function is used for communication between functions division and the main function.
Note that the statement to print c is not executed when b is 0 as the control directly transfers to the catch block after the value os thrown.
This however would not have been possible , had it been IF ELSE here.

Categories