1

I can't understand how to handle an exception in a method which returns value, in my case the value of Person[] type. I tried to do as written here - Creating and Throwing Exceptions, but I'm still getting an exception in - throw icex; line. Could someone please give me a hint? I also tried to return null in catch block, instead of throw, but I only get another exception.(I'm using ArrayList instead of List intentionally)

static ArrayList CreateNonGenericList()
    {            
        ArrayList personList = new ArrayList()
            {
                new Person {FirstName="John", LastName="Clark", Age=39, 
                    StartDate= new DateTime(1989, 12, 30)},
                new Person{FirstName="Zefa", LastName="Thoms", Age=23, 
                    StartDate= new DateTime(2003, 4, 12)},
                new Person{FirstName="Robin", LastName="Hood", Age=33, 
                    StartDate= new DateTime(2001, 4, 12)}
            };
        personList.Add("John"); //Passing a String value instead of Person
        return personList;
    }

    static Person[] SortNonGenericList(ArrayList personList)
    {
        try
        {
            Person[] latestpersonList = (from Person p in personList
                                         where p.StartDate > new DateTime(2000, 1, 1)
                                         select p).ToArray();
            return latestpersonList; 
        }
        catch (InvalidCastException ex)
        {
            InvalidCastException icex = new InvalidCastException(ex.Message, ex);                
            throw icex; //Getting an InvalidCastException here  
        }    
    }        
renchan
  • 519
  • 5
  • 24
  • What is the exception message? – Yuval Itzchakov Feb 17 '15 at 10:07
  • 2
    You are doing a (this way not recommended) rethrow - what did you expect? Your catch-block is redundant. – TGlatzer Feb 17 '15 at 10:09
  • Either remove the entire block so the `InvalidCastException` can propagate, or use `personList.OfType()` to ignore any non-`Person`s, or enumerate using `foreach` and use `if (p is Person)` to do something different depending on the type. It's not clear which is appropriate from your problem statement. – Jeroen Mostert Feb 17 '15 at 10:10
  • @T.Glatzer Actually he's not rethrowing it but creating a new exception with an inner exception set to the old one. That can be useful (although in this case it really isn't). – Dirk Feb 17 '15 at 10:11
  • 1
    What information did you *add* to the exception? You've only managed to *remove* information. So don't do this. – Hans Passant Feb 17 '15 at 10:24
  • It seems that I completely misunderstood the purpose of throw. Thanks for the tips! – renchan Feb 17 '15 at 10:48

1 Answers1

2

If all you want to do is let the caller of your method to handle the exception, you can remove the try/catch block entirely. Exceptions will "bubble up" automatically when they are not caught.

If you would like to do something in the catch block (such as logging) you should throw the original exception:

catch (InvalidCastException ex)
{
    // Log(ex);
    throw;
}

This way the stack trace in the exception is not "reset" as in your current code.

As others have pointed out, what you're currently doing is useless because you're throwing a new exception with the same type and message. Creating a new exception can be useful though if for instance you want a more descriptive exception:

catch (InvalidCastException ex)
{
    throw new ApplicationException("Unable to Sort list because at least one person has no StartDate", ex);
}

The exception would then still "occur" in the catch block, but its description would then provide useful information for that location in the code.

Of course in the end you would have to actually handle the exception. What do you want to do if you can't sort the personList? Return them in their original order? Quit the application? Tell the end user that the operation has failed?

C.Evenhuis
  • 25,996
  • 2
  • 58
  • 72