Exploring Error Handling with Try-Catch Blocks in C#

Firat Tonak
3 min readJan 16, 2023

--

We will explore the topic of handling exceptions in C# within this concise article. In order to manage exceptions effectively, we employ the try-catch-finally block. Here’s a breakdown of its components:

  • Try block: Within the try block, any errors that occur trigger a transfer of control to the catch block.
  • Catch block: In the catch block, we define the logic for handling errors, which may include returning error messages or logging.
  • Finally block: The code in the finally block is executed without exception, serving as the ideal place to implement finalization logic.
try
{
int first = 0;
int second = 0;

int result = first / second;
}
catch (Exception excp)
{
Console.WriteLine("Divide by zero error :\n"+excp.ToString());
}
finally
{
Console.WriteLine("\nWe got an error and need to change the logic here");
}

Indeed, as evident from the preceding explanation, when an error occurs, the try block directs the code flow to the catch block, which in turn directs it to the finally block.

One common source of confusion in exception handling is whether it’s possible to utilize multiple catch blocks. The answer is affirmative; you can indeed have multiple catch blocks, but only one of them will be executed, depending on the type of exception that matches the error encountered.

Another area of confusion in exception handling revolves around the question of whether it’s permissible to use only a try block without incorporating a catch block. The answer is affirmative; you can use a try block by itself, but it is obligatory to include a finally block as part of the structure.

The final aspect to consider in exception handling pertains to the distinction between “Throw ex” and “Throw.” This distinction is crucial for pinpointing the exact source of the issue.

When you employ the “throw” keyword, it allows you to identify the precise line responsible for the problem.

try
{
DivideZero(); // line 25
}
catch (Exception excp)
{
Console.WriteLine(excp.StackTrace);
}

void DivideZero()
{
try
{
int first = 0;
int second = 0;

int result = first / second; // line 39
}
catch (Exception excp)
{

throw;
}
}

The line number may vary depending on your specific environment and configuration.

When you utilize “throw ex,” it will indicate the line where the “throw ex” keyword is located.

try
{
DivideZero(); // line 25
}
catch (Exception excp)
{
Console.WriteLine(excp.StackTrace);
}

void DivideZero()
{
try
{
int first = 0;
int second = 0;

int result = first / second;
}
catch (Exception excp)
{
throw excp;// line 43
}
}

This is why “throw” should be preferred over “throw ex.”

It’s important to emphasize that error handling implementation should be carried out at the higher level rather than at the lower level. When error handling is implemented at the lower level, it becomes impossible to catch errors occurring at the higher level. Conversely, by implementing error handling at the high level, errors can be captured wherever they occur in the code.

In this article, we have explored the fundamental yet crucial topic of error handling. Error handling plays a pivotal role in maintaining the stability and reliability of software applications. For access to the accompanying code, please follow the provided link.

--

--

Firat Tonak

Seasoned Senior Full-Stack .NET Developer sharing hands-on experience and cutting-edge technologies in comprehensive Full-Stack development. #TechInsights