Is the rest of the code inside Try executed after finding Exception?

Asked

Viewed 819 times

9

The rest of the existing code within a try is executed after finding a exception or jumps right into the code inside the catch(Exception e)

try{
  x = 10;
  //alguns erro de try catch
  x = 20;
} catch (Exception e)
{
  x++;
  MessageBox.Show("Valor de x: " + x);
}

In case the message would show 11 or 21?

  • 3

    If the Exception occur on the line you are commenting the result would be 11, for the x would leave the block with value 10.

  • I agree with Fernando, the value of X will be printed as 11.

5 answers

9


Short answer:

It will display the value 11. The value 21 would never be displayed as the catch block is executed only when there is an exception.

Long answer

Come on, straight from MSDN

When an Exception is thrown, the common language Runtime (CLR) looks for the catch statement that Handles this Exception. If the Currently executing method does not contain such a catch block, the CLR looks at the method that called the Current method, and so on up the call stack. If no catch block is found, then the CLR displays an unhandled Exception message to the user and stops Execution of the program.

That is, when an exception is raised, the CLR searches for the closest catch to where this exception was raised and executes its code block. This means that if the current code block where the exception was raised does not have a catch, this catch will be searched in the methods that called it up to reach the top of the call stack, where will be raised an exception of type Unhandled Exception for the user, stopping the execution of the program.

So...

The rest of the existing code within a Try runs after find an Exception or skip directly to the code within the (Catch exception and)

The block try contains the code that can raise an exception, and it will run as long as there is no exception or until it is finalised. In other words, if an exception occurs, it will search directly for the nearest catch without executing the rest of the code within the block try.

The Try block contains the guarded code that may cause the Exception. The block is executed until an Exception is thrown or it is completed successfully. For example, the following Attempt to cast a null Object raises the Nullreferenceexception Exception:

Why this behavior?

An exception indicates that something unusual occurred during the execution of your code. If "something wrong" occurred during this run, do you want the rest of your code to run normally? The block catch should be used precisely to execute a specific code for these abnormal cases, when you you know they can happen.

The catch block can be used in various ways, as can be seen below:

catch(InvalidOperationException ex)
{
  //Deve ser executado quando uma exceção do tipo InvalidOperationException seja levantada
}
catch(SqlException ex) when (ex.Message.Contains("TIMEOUT"))
{
   //Deve capturar uma exceção do tipo SqlException e que contenha no message a palavra TIMEOUT
}
catch(Exception ex)
{
   //Deve capturar uma exceção que não seja uma InvalidOperationException ou **SqlException que não contenha** no message a palavra TIMEOUT
}

Avoid capturing generic exceptions (Exception ex) in specific codes of your application, unless you know what you are doing (logging at the highest point of the system, for example), or raise it again with a throw or by placing it as a Inner Exception. Finally, there are some categories of exceptions that you can use to guide yourself about your treatment:

  • Usage errors: A usage error represents an error in program logic which may result in an exception. However, this type of error should not be solved with a block try catch, and yes with a modification in the code to be executed. It is an error that you know it’s gonna happen and that can be avoided.
  • Program error: A runtime error that cannot be avoided in building the code can fall into this category. Imagine that you need to read a file in a specific directory. Not to fall into Usage error, you check before if this file exists so you can then use it. However, although the check has returned true to the file’s existence, at the time of reading it found itself unavailable (has been deleted or is being used by another process), raising an exception of FileNotFoundException, or similar.
  • System failures: System failures are exceptions that can occur at runtime and that normally cannot be handled very usefully. What you as a developer can do if a OutOfMemoryException? You can however, log the information of this exception in a log before the application is finalized, for further analysis in order to prevent this error from occurring again.

Recommended readings

4

Code execution is stopped at the time the exception is found, so the answer is no. The rest of the code below Exception is not executed.

This is one of the objectives of the structure try/catch. You can predict some error (exception) that the code can generate and handle properly, without the program crashing and displaying errors on the user screen.

try{
  x = 10; //Aqui está atribuindo valor 10 a variável x
  // exceção capturada pelo try/catch
  x = 20; // Essa linha não é executada por causa da exception.
} catch (Exception e)
{
  x++; //x está recebendo ele mesmo (10) mais 1;
  MessageBox.Show("Valor de x: " + x);
}

So the printed message would be Valor de x: 11

4

I put a complete and verifiable example in ideone. And in the .NET Fiddle. Also put on the Github for future reference. Behold also in the Sharplab.

Note that the line of x = 20; has a Warning indicating that it will never be executed. Of course throw were within a method or something conditional this would not occur. But the example is just in case it is certain that the launch of the exception will be executed. The compiler itself informs that it is guaranteed that the code will not be executed in that circumstance.

using System;
public class C {
    public static void Main() {
        int x = 0;
        try {
          x = 10;
          throw new Exception();
          x = 20;
        } catch (Exception) {
          x++;
          Console.WriteLine($"Valor de x: {x}");
        }
    }
}

For those who have more advanced knowledge can help see the IL:

IL_0000: nop
IL_0001: ldc.i4.0
IL_0002: stloc.0
IL_0003: nop
IL_0004: ldc.i4.s 10
IL_0006: stloc.0
IL_0007: newobj instance void [mscorlib]System.Exception::.ctor()
IL_000c: throw
IL_000d: pop
IL_000e: nop
IL_000f: ldloc.0
IL_0010: ldc.i4.1
IL_0011: add
IL_0012: stloc.0
IL_0013: ldstr "Valor de x: {0}"
IL_0018: ldloc.0
IL_0019: box [mscorlib]System.Int32
IL_001e: call string [mscorlib]System.String::Format(string, object)
IL_0023: call void [mscorlib]System.Console::WriteLine(string)
IL_0028: nop
IL_0029: nop
IL_002a: leave.s IL_002c
IL_002c: ret

3

In addition to what has already been said, if you want a block of code to be executed despite being caught an exception, you can include the Finally after the Catch.

   try 
   {
        // Código a executar
   }
   catch(Exception)
   {
        // Código para tratar a excepção
   }
   Finally
   {
        // Código a executar mesmo que seja accionada uma excepção
        // Exemplo: Fechar um ficheiro que tenha sido aberto pelo System.IO.StreamReader 
   }

2

The value of X will be 11 if the exception is triggered between: X = 10 and X = 20.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.