PHP exceptions in foreach loop - php

Which is the right way to implement php exception (try{}catch(){}) in a foreach loop that looks like this:
foreach ($apis as $api)
{
$api = '_'.$api;
$searchResults[$api] = $this->$api($parameters);
}
I want to implement the php exceptions for if one of the $this->api(); returns an error message, than catch it and do a if inside the catch to display the right message for the error message returned.
Edit:
Also, when capturing the error and if the error message is 1 (for example) is it a good way to do:
$searchResults['api'] = $this->_api($parameters);
so it tries to do the function again and see if this time it brings valid data?

foreach ($apis as $api)
{
$api = '_'.$api;
try {
$searchResults[$api] = $this->$api($parameters);
}
catch(ParameterException $e) {
// parameterexception handling here
echo "A ParameterException was thrown";
}
catch(Exception $e) {
// All other exceptions
echo "Some other Exception was thrown";
}
}
You can differentiate between more Exception-Types as well.

Since the catch block will be executed only in case of an exception, it really makes no difference if you wrap the for-each loop inside the try block, or if you put the try-catch inside the loop's body.
You should take whatever adds more clarity. However, doing it inside the loop will enable you to handle more specific exceptions relevant to the loop's body if the need arises in the future.
Also, since exceptions are typed, you don't need to do an if, just put different catch clauses:
try {
:
} catch (FirstExceptionType $e) {
:
} catch (SecondExceptionType $e) {
:
}

The code you use will always fail, because you are trying to use a variable ($this->$api($params);) as a function. How ever, you could implement your try-catch as follows:
foreach ($apis as $api)
{
$api = '_'.$api;
try {
$searchResults[$api] = $this->$api($parameters);
}
catch(Exception $e) {
// handle exception
}
}
You can also handle multiple Exceptions of different types by adding another catch() with another Exception class inside it, like:
foreach ($apis as $api)
{
$api = '_'.$api;
try {
$searchResults[$api] = $this->$api($parameters);
}
catch(OtherException $e) {
// Handle it
}
catch(Exception $e) {
// Handle it
}
}

Related

Using continue in try-catch to prevent script termination when exception is thrown

I want to convert an old code to use exception, but it shouldn't stop when exception is thrown. That's the old code:
function update()
{
foreach ($this->instances as $id => $instance)
{
if ($instance->exists())
{
if (!$instance->save())
{
$this->setError($instance->getError());
continue;
}
continue;
}
}
If I want to use try catch block, do I need to use continue to avoid the script stop? That's the code with try-catch:
function update()
{
foreach ($this->instances as $id => $instance)
{
if ($instance->exists())
{
try
{
$instance->save();
}
catch (exception $e)
{
echo $e->getMessage();
}
}
}
There is no need to add a continue keyword.
If an exception is thrown in the try block, the code in the catch block will be executed. After that the rest of the code will be executed normally.
Read the section about exceptions in the language reference for details.

When it comes to handle errors, in what sense, using Exceptions are better that utilize if...else...switch... etc.?

I perfectly understand the nuances of the (try/throw/catch) block.
What I don't understand is:
If we gonna use an IF (or any control structure) inside our try block anyway in order to test if a condition is met, only then, 'throw' an exception if the results of that test is false, then... in my opinion: throw/generate an exception is useles; because if a condition is not met, we can simply print an error message, call a function, instantiate a class, redirect to another location, etc.
Another story would be, if for instance, a variable was not initialized, we enclose that variable inside a try{} block, echo the variable, and from that point onward, everything will be handle by the catch() block because the try block raises an error; and since the try/catch blocks talk each other, the catch block will catch every error that was originated from his corresponding try block. However, you can set a custom error message inside yout try block (optional).
What I've read so far:
every results from searching: if vs. try
I do see the difference.
But I can not understand why some people choose try/throw/catch over if...else...switch...while... etc.
As far I can see, try/throw/catch can be used for debugging, though.
One benefit of exceptions over if/then is that you can wrap try/catch around a large block of code. It will be triggered if an error happens anywhere in the block.
try {
$db = db_open();
$statement = $db->prepare($sql);
$result = $statement->execute($params);
} catch (Exception $e) {
die($e->getMessage());
}
With if/then, you would have to perform a test at each step.
$db = db_open();
if (!$db) {
die(db_connect_error());
}
$statement = $db->prepare($sql);
if (!$statement) {
die(db_error($db));
}
$result = $statement->execute($params);
if (!$result) {
die(db_error($db));
}
As you said, it's a lot of overhead to throw an exception inside a try/catch block and catch it immediately.
try {
if (...) {
// good, do no throw
} else {
throw new Exception();
}
} catch ($e) {
// handle exception
}
This should be replaced by:
if (...) {
// good
} else {
// handle error, no exception
}
Exceptions are useful because they bubble up. So imagine if you have this code instead:
function bla() {
try {
tryToDoSomething();
} catch ($e) {
// handle error
}
}
function tryToDoSomething() {
if ($somethingNotAvailable) {
throw new Exception();
}
doSomething();
}
In this case, the function that defines the try/catch is NOT the one throwing the exception. tryToDoSomething() does not know how to handle the errors so it will let parent methods to take care of it. The exception can bubble up the call stack until someone catches it and handles the error. That's how exceptions can actually be useful :)

PHP exception inside catch: how to handle it?

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?
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
}
}
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;
}
You have 2 possible ways:
You exit the program (if it is severe) and you write it to a log file and inform the user.
If the error is specifically from your current class/function,
you throw another error, inside the catch block.
You can use finally. Code in this branch will be executed even if exception is thrown within catch branch

Get all the exceptions from one try catch block

I wonder if it's posible to get all the exceptions throwed.
public function test()
{
$arrayExceptions = array();
try {
throw new Exception('Division by zero.');
throw new Exception('This will never get throwed');
}
catch (Exception $e)
{
$arrayExceptions[] = $e;
}
}
I have a huge try catch block but i want to know all the errors, not only the first throwed. Is this possible with maybe more than one try or something like that or i am doing it wrong?
Thank you
You wrote it yourself: "This will never get throwed" [sic].
Because the exception will never get thrown, you cannot catch it. There only is one exception because after one exception is thrown, the whole block is abandoned and no further code in it is executed. Hence no second exception.
Maybe this was what the OP was actually asking for. If the function is not atomic and allows for some level of fault tolerance, then you can know all the errors that occurred afterwards instead of die()ing if you do something like this:
public function test()
{
$arrayExceptions = array();
try {
//action 1 throws an exception, as simulated below
throw new Exception('Division by zero.');
}
catch (Exception $e)
{
//handle action 1 's error using a default or fallback value
$arrayExceptions[] = $e;
}
try {
//action 2 throws another exception, as simulated below
throw new Exception('Value is not 42!');
}
catch (Exception $e)
{
//handle action 2 's error using a default or fallback value
$arrayExceptions[] = $e;
}
echo 'Task ended. Errors: '; // all the occurred exceptions are in the array
(count($arrayExceptions)!=0) ? print_r($arrayExceptions) : echo 'no error.';
}

Cleanest way to execute code outside of try block only if no exception is thrown

This question is about the best way to execute code outside of try block only if no exception is thrown.
try {
//experiment
//can't put code after experiment because I don't want a possible exception from this code to be caught by the following catch. It needs to bubble.
} catch(Exception $explosion) {
//contain the blast
} finally {
//cleanup
//this is not the answer since it executes even if an exception occured
//finally will be available in php 5.5
} else {
//code to be executed only if no exception was thrown
//but no try ... else block exists in php
}
This is method suggested by #webbiedave in response to the question php try .. else. I find it unsatisfactory because of the use of the extra $caught variable.
$caught = false;
try {
// something
} catch (Exception $e) {
$caught = true;
}
if (!$caught) {
}
So what is a better (or the best) way to accomplish this without the need for an extra variable?
One possibility is to put the try block in a method, and return false if an exception is cought.
function myFunction() {
try {
// Code that throws an exception
} catch(Exception $e) {
return false;
}
return true;
}
Have your catch block exit the function or (re)throw/throw an exception. You can filter your exceptions as well. So if your other code also throws an exception you can catch that and (re)throw it. Remember that:
Execution continues if no exception is caught.
If an exception happens and is caught and not (re)throw or a new one throw.
You don't exit your function from the catch block.
It's always a good idea to (re)throw any exception that you don't handle.
We should always be explicit in our exception handling. Meaning if you catch exceptions check the error that we can handle anything else should be (re)throw(n)
The way I would handle your situation would be to (re)throw the exception from the second statement.
try {
$this->throwExceptionA();
$this->throwExceptionB();
} catch (Exception $e) {
if($e->getMessage() == "ExceptionA Message") {
//Do handle code
} elseif($e->getMessage() == "ExceptionB Message") {
//Do other clean-up
throw $e;
} else {
//We should always do this or we will create bugs that elude us because
//we are catching exception that we are not handling
throw $e;
}
}

Categories