Home > Software design >  C# How to append details to exception
C# How to append details to exception

Time:07-12

I'm trying to handle exceptions being thrown in a worker function. My goal is to only throw one exception with all necessary details up to the calling function, who then decides if it needs to be logged or to alert the user, etc. But I would prefer to preserve the function and line number where the exception was thrown. Here is a simple example (Console.WriteLine() in place of my logging function, for simplicity):

try
{
    string arg = "[Important-Details]";
    Worker(arg);
}
catch (Exception ex)
{
    Console.WriteLine(ex.ToString()); //this is where I would log or pop-up message
}

and here is the worker function:

public static void Worker(string details)
{
    try
    {
        int i = 1;
        int j = 0;
        int k = i / j; //line90
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Failed function with details:{details} - {ex.ToString()}"); //shows line90
        throw; //shows this line
    }
}

The WriteLine() inside the worker function will show line90 (line with i / j). This provides some useful information - I have the exact line where the exception was thrown - but it doesn't tell me who called the worker. Throwing up this exception, and I lose the details I wrote ("Failed function with details:{details}"), plus it resets the line number to the "throw" line.


Although it is possible to attain all the information needed by looking at both logs, I would rather only pass up one exception and then make the decision of what to do with it. Is there a snazzy way to do this, or nothing can be done?

CodePudding user response:

The standard way to solve this is to threw a new exception in the exception handler of the Worker function with an InnerException that contains the original exception:

public static void Worker(string details)
{
    try
    {
        int i = 1;
        int j = 0;
        int k = i / j; //line90
    }
    catch (Exception ex)
    {
        // Provide the original exception as inner exception to the new exception
        throw new ApplicationException($"Worker failed with details: {details}", ex); 
    }
}

This allows to add additional details and preserves the original exception, so that the call to ex.ToString() in the calling function gives this output with both the details and the original line number:

System.ApplicationException: Worker failed with details: [Important-Details] ---> System.DivideByZeroException: Attempted to divide by zero. at Program.Worker(String details) in d:\Windows\Temp\hpojx1gl.0.cs:line 11 --- End of inner exception stack trace --- at Program.Worker(String details) in d:\Windows\Temp\hpojx1gl.0.cs:line 15 at Program.Main() in d:\Windows\Temp\hpojx1gl.0.cs:line 23

I've built a sample on dotnetfiddle; the division by zero is done in line 11 in this case.

  • Related