views:

165

answers:

10

If I have a routine that can throw an ArgumentException in two places, something like...

if (Var1 == null)
{
    throw new ArgumentException ("Var1 is null, this cannot be!");
}

if (Val2  == null)
{
    throw new ArgumentException ("Var2 is null, this cannot be either!");
}

What’s the best way of determining in my calling procedure which of the two exceptions was thrown?

Or

Am I doing this in the wrong fashion?

+4  A: 

Your calling function should not care which line caused the exception. In either case an ArgumentException was thrown, and both should be dealt with the same way.

Justin Ethier
+1 Also this could easily be checked prior to calling the method.
Skurmedel
but if i wanted to dispaly a specific message to the user depending on which of the two exceptions was thrown?
Rob
You could either use the text from the exception itself, or throw `ArgumentNullException` instead.
Justin Ethier
+11  A: 

Pass the name of the variable (Val1, Val2 etc) in the second argument to the ArgumentException constructor. This becomes the ArgumentException.ParamName property.

ShellShock
+11  A: 

For this specific scenario you should be using ArgumentNullException and correctly fill it's ParamName property so that you know the argument that is null.

The class ArgumentException also supports the same property but you should used the most specific exception type available.

When using these types of exceptions also be careful when using the constructor that accept both the message and the parameter name. The orders are switched between each exception type:

throw new ArgumentException("message", "paramName");

throw new ArgumentNullException("paramName", "message");
João Angelo
A: 
try
        {
            //code here
        }
        catch (ArgumentException ae)
        {
            Console.WriteLine(ae.ToString());
        }

The output in your console will tell the message you've put.

djerry
+3  A: 

Use the constructor ArgumentException(string, string) to define, which parameter was null.

if (Var1 == null) {
  throw new ArgumentException ("Var1 is null, this cannot be!","Var1");
}

if (Val2  == null){
  throw new ArgumentException ("Var2 is null, this cannot be either!","Var2");
}
Jehof
+2  A: 

Well, for an ArgumentException in particular you have a parameter for which argument had a problem:

throw new ArgumentException("Var1 is null, this cannot be!", "Var1");

In a more general sense, you usually would do something like use different (possibly custom) exception types, and then the calling code can have different catch blocks

public class MyCustomException1 : ApplicationException {}
public class MyCustomException2 : ApplicationException {}


try
{
 DoSomething();
}
catch(MyCustomException1 mce1)
{
}
catch(MyCustomException2 mce2)
{
}
catch(Exception ex)
{
}
Clyde
In this situation the second argument to the ArgumentException should be a string, i.e., the name of the offending parameter.
ShellShock
whoops...of course you're right
Clyde
+3  A: 

The bigger question you should be asking yourself is why? If you are trying to drive some sort of logic off of this, then exceptions are generally a bad way to go.

Rather, you should have a return type (or out/ref parameter) which will be set with a flag/value of some sort that you can detect from the calling code to determine what the error is and drive your logic off that.

If you insist on using exceptions, then in this case, the ArgumentNullException has a constructor that takes the name of the parameter and the exception message. You can throw the exception and then when you catch the exception, access the ParamName property to determine the name of the parameter which caused the exception.

casperOne
A: 

When throwing ArgumentExceptions you can always include the name of the argument causing the exception (it's another constructor). Of course I'm assuming you really want to know which one was null and in that case, you should probably use the ArgumentNullException.

Austin Salonen
A: 

If this is for a test case where you want to make sure the right exception message is being displayed, I know NUnit has an ExpectedMessage keyword to the ExpectedException attribute. Otherwise, an ArgumentNullException is an ArgumentNullException and your application should treat them all the same. If you want more detail, create your own exception classes and use those.

So you could test for the following:

[ExpectedException(typeof(ArgumentNullException), ExpectedMessage="Var1 is null, this cannot be!"]
public void TestCaseOne {
    ...
}

[ExpectedException(typeof(ArgumentNullException), ExpectedMessage="Var2 is null, this cannot be either!"]
public void TestCaseTwo {
    ...
}
Daniel DiPaolo
+2  A: 

You don't really provide enough information to answer your question. The obvious answer is to look at the message of the exception, but I'm guessing that isn't what you're looking for.

If it's truly important that you be able to tell them apart programatically, then use another exception, or at least use the paramName property of the current exception's constructor. That will give you somewhat more relevant information.

However, using your own exception type is the only way to guarantee that you're catching the exception for a particular circumstance. Because ArgumentException is part of the framework, it's possible that something else that you call might throw it, which would lead you into the same catch block. If you create your own exception type (either one for both or one for each of the scenarios), this will provide you with a way to handle the specific error. Of course, judging by your example, it seems like it would be simpler just to check and see if Val1 or Val2 is null before you call the function to begin with.

Adam Robinson