Tunahan
Tunahan

Reputation: 303

How to detect the source of exceptions in c#?

This is a sample case for asking the question in my mind. I have a try block which contains Convert.ToInt32 and DateTime.ParseExact method calls. When catching FormatException, how could I detect the method that throws exception?

Sample code:

try
{
    //mStrToDate and mStrToInt are the variables that contains desired time and integer values in string format
    DateTime myDate = DateTime.ParseExact(mStrToDate, "yyyy-MM-dd HH:mm:ss,fff", System.Globalization.CultureInfo.InvariantCulture);
    int mIntVar = Convert.ToInt32(mStrToInt);
}
catch (FormatException exc)
{
    Console.WriteLine(exc.Message);//this line must specify the exception source 
}

Upvotes: 2

Views: 3611

Answers (3)

Metin Atalay
Metin Atalay

Reputation: 1517

similar to my example , maybe usefull your question

try
    {
        //mStrToDate and mStrToInt are the variables that contains desired time and integer values in string format
        DateTime myDate = DateTime.ParseExact(mStrToDate, "yyyy-MM-dd HH:mm:ss,fff", System.Globalization.CultureInfo.InvariantCulture);
        //int mIntVar = Convert.ToInt32(mStrToInt);

        string line = Console.ReadLine();
        if (!int.TryParse(line, out mIntVar ))
        {
            Console.WriteLine("{0} is not an integer", line);
            // Whatever
        }

    }
    catch (FormatException exc)
    {
        Console.WriteLine(exc.Message);//this line must specify the exception source 
    }    

or you can this simple code

string line = Console.ReadLine();
int mIntVar ;
if (!int.TryParse(line, out mIntVar ))
{
    throw new FormatException();
}

Upvotes: -1

Pac0
Pac0

Reputation: 23129

If you want to do so, if you know that both of your statements can throw the same exception as in your example, you should use different try-catch blocks .

try
{
    DateTime myDate = DateTime.ParseExact(mStrToDate, "yyyy-MM-dd HH:mm:ss,fff", System.Globalization.CultureInfo.InvariantCulture);
}
catch (FormatException exc)
{
    Console.WriteLine("Exception from DateTime.Parse" + exc.Message);
}

try
{
    int mIntVar = Convert.ToInt32(mStrToInt);
}
catch (FormatException exc)
{
    Console.WriteLine("Exception from Convert.ToInt32 " + exc.Message);
}

You could write some kind of wrapper that, given a list of calls (actions), will execute the action in a try catch block. That would likey solve (or improve on) the problem of doing all this cleanly on a large number of calls.


Other approaches :

Dig info from the exception message :

In some cases, there could be some info in the message itself, but this seems smelly to use a hypothetical part of the string message to classify your result and infer the source.

If identifying the source of the exception is important to you, you should not rely on some message behavior, which might change without notice and break your code.

Dig info from the exception stack trace :

The call stack could be used, it seems more reliable to me but much more complicated . But it should work for your case.

Do not use exceptions

As mentionned several time in the comments, there is the "tryParse" approach, that is likely to solve your issue in better way. If the parsings are expected to fail sometimes, then it's not an exception.

It's part of your normal program flow, and you should treat it as such (with try parse and conditional logic depending on the success of the parsing)

Upvotes: 2

Gerrie Pretorius
Gerrie Pretorius

Reputation: 4121

try
{
    //mStrToDate and mStrToInt are the variables that contains desired time and integer values in string format
    DateTime myDate = DateTime.ParseExact(mStrToDate, "yyyy-MM-dd HH:mm:ss,fff", System.Globalization.CultureInfo.InvariantCulture);
    int mIntVar = Convert.ToInt32(mStrToInt);
}
catch (Exception exc)
{
    Console.WriteLine(MethodWhereExceptionOccured(ex));//this line must specify the exception source 
}

Method to get where error occured

    public static string MethodWhereExceptionOccured(Exception ex)
    {
        return ex.StackTrace.Split('\r').First().Trim();
    }

Upvotes: 1

Related Questions