Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass the exception caught in inner catch to outer catch in a nested try catch

I am nesting try catches inside of a main try catch statement, what I would like to know is how I can make the main try catch fail if one of the nested try catches fails?

Here is my code:

try 
{    
    try 
    {
        //how can I make the main try catch fail if this try catch fails?
    } 
    catch(Exception $e)
    {
        error_log();
    }       
} 
catch(Exception $e)
{
    error_log();
}
like image 978
Odyss3us Avatar asked Jun 23 '11 16:06

Odyss3us


People also ask

How do you resolve a nested try catch?

How to Avoid the Nesting? Extracting the nested part as a new method will always work for any arbitrarily nested Try-Catch-Finally block.

Can there be a nested try catch block inside a try catch block?

Yes, we can declare a try-catch block within another try-catch block, this is called nested try-catch block.

What happens if exception occurs inside catch block?

Answer: When an exception is thrown in the catch block, then the program will stop the execution. In case the program has to continue, then there has to be a separate try-catch block to handle the exception raised in the catch block.

Is it good to have nested try catch?

Nesting try-catch blocks severely impacts the readability of source code because it makes it to difficult to understand which block will catch which exception.


4 Answers

After error_log(); in the first try-catch, type throw $e; (on a new line). This will throw the error again, and the outer try-catch will handle it.

like image 199
zsalzbank Avatar answered Oct 05 '22 04:10

zsalzbank


You should extend Exception for the various different types of Exception. That way you can trigger a specific try-catch block:

try
{
  ...
  try
  {
    throwSomeException();
  }
  catch ( InnerException $e )
  {
    ...do stuff only for InnerException...
  }
  ...
}
catch ( Exception $e )
{
  ...do stuff for all types of exception...
}

Additionally, you can chain your catch statements to trigger different blocks in a single try-catch:

try
{
  ...
}
catch ( SpecificTypeOfException $e )
{
  ..do something specific
}
catch ( TypeOfException $e )
{
  ..do something less specific
}
catch ( Exception $e )
{
  ..do something for all exceptions
}
like image 34
zzzzBov Avatar answered Oct 05 '22 03:10

zzzzBov


Inside the inner catch, throw() - NOT recommended, I've seen several issues with PHP when doing this. Or set a flag to throw just after the inner catch.

Here's an example throwing the same exception (or you could throw a different one).

try {
    $ex = null;
    try {
        //how can I make the main try catch fail if this try catch fails?
    } catch(Exception $e){
        $ex = $e;
        error_log();
    }

    if ($ex) {
       throw $ex;
    }

} catch(Exception $e){
    error_log();
}
like image 35
evan Avatar answered Oct 05 '22 05:10

evan


I handle exceptions in a way similar to eventHandling in Javascript. An event bubbles up the ladder from specific to generic. When it reaches the start program, an exception lost all it's meaning to the code and should simply be caught for logging and ending an application.

In the meantime a lot of stuff can happen

CallStack:

  • Start Lunch
  • Eat Apple (Before this code, an apple was bought as lunch)
  • Sink teeth in apple

During my eating of the apple, a worm appeared:

throw NausiaException('I found a bleeding worm...');

Eat Apple scope catches

catch(Exception $e)

the exception because in that scope we can return the apple to the store and shout at the manager. Since nothing more useful can be said about the occurrence,

throw $e

is called because eating the apple failed.

Something could've gone different However, if the store manager refused to refund, you can wrap the exception

throw new RefundFailedException('The manager is a cheap skate', RefundFailedException::REFUSED, $e)

Start lunch Scope Start lunch scope wants to throw away bad lunch

try {
    //Start lunch
} catch (Exception $e) {
    switch (true) {
        case $e instanceof NausiaException:
        case $e instanceof RefundFailedException:
            //Throw lunch away
            break;
    }
}
like image 36
Kurimasta Avatar answered Oct 05 '22 04:10

Kurimasta