I have a very simple check right at the beginning of one of my methods as follows:
public void MyMethod(MyClass thing)
{
if(thing == null)
throw new ArgumentNullException("thing");
//Do other stufff....
}
But I'm getting stacktraces (from Elmah in a production environment) which appears to indicate that the "if(thing == null)" line is throwing a NullReferenceException. The first 2 lines of the stack trace are something like:
System.Web.HttpUnhandledException: Exception of type 'System.Web.HttpUnhandledException' was thrown. ---> System.NullReferenceException: Object reference not set to an instance of an object.
at MyLibrary.BL.AnotherClass.MyMethod(MyClass thing) in C:\Development\MyProject\trunk\MyLibrary.BL\AnotherClass.cs:line 100
MyClass is a fairly simple class with no operator overloads or anything like that, so I'm a bit stumped as to what is throwing the NullReferenceException!
Can anybody suggest scenarios that might cause this?
EDIT: I suspect "thing" might be null, but I really would expect an ArgumentNullException not a NullReferenceException - this is basically what this question is about. Is there maybe something that the framework or Elmah that is changing or mis-reporting the exception - or is the only explanation that the binaries are somehow out of date?
It is impossible for if (thing == null) to throw a NullReferenceException.
This means that something else is going on. It's time to start using your imagination in conjunction with a firm resolve to ignore the possibility that the if caused a problem.
The if statement can throw a NullReferenceException if MyClass defines the == operator incorrectly e.g.
class MyClass
{
int A {get;set;}
public static bool operator ==(MyClass a, MyClass b)
{
return a.A == b.A;
}
public static bool operator !=(MyClass a, MyClass b)
{
return !(a == b);
}
}
Looks like the exception is coming from something up the chain that calls MyMethod. MyMethod() is throwing the Exception and nothing above is handling it, so whatever web framework you're in is throwing the HttpUnhandledException.
I also encountered this impossible situation. It turned out to be due to the use of the as keyword, I have no idea why. I was using the SharpPdf library and had a line of code like this:
var destElement = annotDict.Elements["/Dest"] as PdfName;
if (destElement == null)
{
continue;
}
If I remove the as PdfName portion, it works. So I now have two levels of checking in my code:
var destElement = annotDict.Elements["/Dest"];
if (destElement == null)
{
continue;
}
var destElementName = destElement as PdfName;
if (destElementName == null)
{
continue;
}
thing is null.
That would cause it.
[EDIT]: Here's the code I tested with:
protected void Button3_Click(object sender, EventArgs e)
{
MyMethod(null);
}
public void MyMethod(String thing)
{
if (thing == null) // This caused the exception to be thrown.
throw new Exception("test");
//Do other stufff....
}
Related
From what I've seen, ArgumentExceptions are usually used like such:
public void UpdateUser(User user)
{
if (user == null) throw new ArgumentException("user");
// etc...
}
but what if I have something like this:
public void UpdateUser(int idOfUser)
{
var user = GetUserById(idOfUser);
if (user == null) throw new ArgumentException("idOfUser");
// etc...
}
Is that still an ArgumentException?
The first
if (user == null) throw new ArgumentException("user");
should be
if (user == null) throw new ArgumentNullException("user");
If possible you shouldn't throw ArgumentException directly
The primary derived classes of ArgumentException are ArgumentNullException and ArgumentOutOfRangeException. These derived classes should be used instead of ArgumentException, except in situations where neither of the derived classes is acceptable.
For the second example, here Should I throw a KeyNotFoundException for a database lookup? they suggest (in comments)
if (user == null) throw new ObjectNotFoundException();
It is defined in System.Data: System.Data.ObjectNotFoundException.
As the name suggests, an ArgumentException is an exception about an argument. It means the argument was somehow inherently wrong.
The general form is:
public void SomeMethod(SomeType arg)
{
if(!TestArgValid(arg))
throw new ArgumentException("arg"); //Or more specific is possible
//e.g. ArgumentNullException
/* Actually do stuff */
}
If the only possible way that GetUserById could fail was that there was something inherently incorrect with the value of idOfUser then the following would both be the same in practice:
public void UpdateUser(int idOfUser)
{
if(!TestValid(idOfUser))
throw new ArgumentException("idOfUser");
var user = GetUserById(idOfUser);
// Do stuff with user
}
public void UpdateUser(int idOfUser)
{
var user = GetUserById(idOfUser);
if(user == null)
throw new ArgumentException("idOfUser");
// Do stuff with user
}
And if it turned out to be for some reason faster or less wasteful of some resource to test user after the fact than idOfUser before the fact and if there were no side-effects of calling GetUserById, and if the difference actually mattered then maybe the second version would be a reasonable optimisation of the first.
But that only holds if all of the ifs above hold, and it's then a weird way of detecting an invalid argument that has some specific advantage where we benefit from the encapsulation of methods by hiding that weirdness from everything else.
Chances are there could be a valid idOfUser for which there was no corresponding user, in which case it certainly wasn't an argument exception.
I have a function that needs to throw an exception, but I wanted it to throw that exception to the line where I called that function:
static int retrieveInt()
{
int a = getInt();
if(a == -1)
throw new Exception("Number not found"); //The runtime error is pointing to this line
return a;
}
static void Main(string[] args)
{
int a = retrieveInt(); //The runtime error would be happening here
}
After 2 hours searching I found the answer to my question. To do what I wanted it is needed to user [System.Diagnostics.DebuggerStepThrough] before the function:
[System.Diagnostics.DebuggerStepThrough]
static int retrieveInt()
{
int a = getInt();
if(a == -1)
throw new Exception("Number not found"); //The runtime error will not be here
return a;
}
static void Main(string[] args)
{
int a = retrieveInt(); //The runtime error happens now here
}
The described behaviour is not strictly possible, but working around to the desired effect is.
The issue you're running into is that in Visual Studio, execution pauses and we see exceptions from the most available location with debug info. For framework methods, this means the method call, even though the exception is being thrown a couple of calls deeper. Since the exception is coming from the same project you're debugging, you'll always have debug info for the actual throw line, and thus you'll always reach that line.
The workaround here is to utilize the Call Stack window in VS, which will include a couple lines down the method call which triggered the error, and double-clicking on this will bring you where you want to be, including all local variables at the time of the call. This is analogous to the framework exception behaviour, because if you look at the stack trace, several frames are marked as "external" because they don't have debug info.
EDIT: To add some info about the behaviour of try and catch, catch will respond to any exception not already caught - thus, even if the exception is thrown several calls deeper, if it's not handled by the time the call stack unwinds into your try block, it'll hit the appropriate catch block (if there is one).
How about this ?
public static int NewInt
{
get
{
throw new Exception("Number not found");
}
}
static void Main(string[] args)
{
int a = NewInt;
}
I am using reflection to set properties on an object. If any of the setters throw an exception, the exception is not caught by the code that makes the SetValue call. Visual Studio tells me that the exception is uncaught by user code.
For example, imagine in the example below that the Title property setter on the object referenced by the "target" variable throws an ArgumentException.
Looking at the call stack, it seems that there is unmanaged code between the snippet below and the setter.
Can somebody please (& thank you!) explain:
Why is this happening in the first place?
Is there a simple way to fix it without re-thinking the program logic?
Here is my code:
try
{
prop.SetValue(target, attr.Value); // target does have a "Title" property
// attr.Value == "Title"
// the setter throws an ArgumentException
}
catch (Exception ex) // No exception is ever caught.
{
errors.Add(ex.Message);
}
Here is the code for one of many properties that I want to set like this:
public string Title
{
get
{
return this.title;
}
set
{
if (string.IsNullOrEmpty(value) || value.Length < 1 || value.Length > 128)
{
throw new ArgumentException("Title must be at least 1 character and cannot be longer than 128 characters.");
}
this.title = value;
}
}
EDIT as stated by #Default, Framework 4.5 does have an overload with only two parameters, so if the user is working with FW 4.5 this answer does not have relevance (at least the last part about PropertyInfo),
You are wrong, it is trapped and here is an example to demonstrate it:
public class ExceptionGenerator
{
public static void Do()
{
ClassToSet clas = new ClassToSet();
Type t = clas.GetType();
PropertyInfo pInfo = t.GetProperty("Title");
try
{
pInfo.SetValue(clas, "test", null);
}
catch (Exception Ex)
{
Debug.Print("Trapped");
}
}
}
class ClassToSet
{
public string Title {
set {
throw new ArgumentException();
}
}
}
What you are doing wrong is obtaining the PropertyInfo, the PropertiInfo's SetValue method expects a third parameter, the index at the property (null in your case), so your "prop" is not a PropertyInfo, I assume it's a FieldInfo, and because that it throws an unhandled exception.
Any exception there should be caught.
See fiddle: https://dotnetfiddle.net/koUv4j
This includes errors in the reflection call itself (setting the property to the wrong Type), or having an exception within the property's setter itself (set throws).
This leads to something else being wrong. Possibilities:
You've got your IDE set to halt on all exceptions
The exception isn't happening where you think it is (like, in the catch, which will rethrow)
If it's not one of those 2 then please provide more information.
In Framework Design guideline book there is a chapter about Exception and they talk about return-value-based error reporting and exception based error reporting and the fact that we in a O.O language like C# we should avoid return-value-based error reporting and use exceptions. With that in mind I was looking at our code that eight years ago was written in Visual Basic and last year with a automatic tool got converted to C#!
So here is a method I am looking at, I was wondering if the advice from that book applies to such a method and if yes, then what would be a better approach for rewriting this method?
public int Update(CaseStep oCaseStepIn)
{
int result = 0;
//Update the master object with the passed in object
result = UCommonIndep.gnUPDATE_FAILED;
if (Validate(oCaseStepIn) == UCommonIndep.gnVALIDATE_FAILED)
{
return result;
}
CaseStep oCaseStep = get_ItemByObjectKey(oCaseStepIn.CopyOfObjectKey);
if (oCaseStep == null)
{
return result;
}
return result;
}
Throw specific exceptions when possible. Then, you don't need a return value in this case.
public void Update(CaseStep oCaseStepIn)
{
//Update the master object with the passed in object
if (Validate(oCaseStepIn) == UCommonIndep.gnVALIDATE_FAILED)
throw new ValidationFailedUpdateException();
CaseStep oCaseStep = get_ItemByObjectKey(oCaseStepIn.CopyOfObjectKey);
if (oCaseStep == null)
throw new KeyObjectNotFoundUpdateException();
if (oCaseStep.Update(oCaseStepIn) != UCommonIndep.gnUPDATE_SUCCESSFUL)
throw new UpdateFailedException();
//*******************************
//FYI - Insert code here to update any Key values that might have changed.
}
UpdateFailedException extends Exception
ValidationFailedUpdateException extends UpdateFailedException
KeyObjectNotFoundUpdateException extends UpdateFailedException
There are (at least) as many opinions on exception handling as there are coders, but a good rule of thumb to start from is that exceptions should be thrown in exceptional circumstances.
So, is an update failure an exceptional occurrence?
Is this the best way for me to abort instantiation of an object if it's parameters are not passed in with valid data?
protected Command(string commandKey)
{
if(commandKey == null) throw new ArgumentNullException("commandKey", "Command Key cannot be null as it is required internally by Command");
if(commandKey == "") throw new ArgumentException("Command Key cannot be an empty string");
CommandKey = commandKey;
}
Yes. It is common practice to validate the arguments in constructors and throw an exception if they are invalid.
It's perfectly fine. Constructors do not return anything so how else would you know if something went wrong? You could have a bool to set it to some uninitialized state but I would go with exceptions.
Also :
if(String.IsNullOrEmpty(commandKey)) //throw exectpion
In this case you could use the static method string.IsNullOrEmpty(commandKey):
protected Command(string commandKey)
{
if(string.IsNullOrEmpty(commandKey))
throw new ArgumentException("commandKey");
//something
}
This is exactly what Microsoft does if you look through the framework source code, so I suspect it is perfectly valid.
It is perfectly fine if you validate inside a constructor and throw exception if something goes wrong.