I find the C# exceptions very annoying, because they provide so less information. What is the reason for this?
NullReferenceException or KeyNotFoundExceptions are hard to debug and sometimes you donĀ“t get a linenumber in the stacktrace. Why can the exception itself not provide more informations?
For example:
private Dictionary<string, object> Properties = null;
public void Process(string key)
{
var item = this.Properties[key];
....
}
When "Properties"is null I get a NullReferenceException:
"System.NullReferenceException: Object reference not set to an instance to an object"
Why I do not get:
"System.NullReferenceException: Object reference 'Properties' not set to an instance to an object"
This would be more usefull and the CLR does know, which reference is null.
The same when I pass a non existent key e.g. Process("dummy"):
"System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary"
Why I do not get:
"System.Collections.Generic.KeyNotFoundException: The key 'dummy' was not present in the dictionary"
The CLR knows, which key was passed and not found.
I try to debug such errors (which illegal keys are passed) in an productive environment
and made the code more robust like:
private Dictionary<string, object> Properties = null;
public void Process(string key)
{
if (this.Properties != null)
{
if (this.Properties.ContainsKey(key))
{
var item = this.Properties[key];
...
}
else
{
throw new KeyNotFoundException(string.Format("The key '{0}' was not found.", key));
}
}
else
{
throw new NullReferenceException(string.Format("The object 'Properties' is null."));
}
}
But why I have to do this, normally the CLR could tell me what was going wrong in detail. I cannot wrap all codepieces like this to get more informations when an exception happens.
For your KeyNotFoundExceptions, you can create your own dictionary class that throws more meaningful messages (I recommend you try to extend KeyNotFoundException and throw that), or you can use TryGetValue and throw a meaningful exception.
The NullReferenceException one, however, is much more complicated: you assume that the CLR knows that the thing is called Properties, but it's not so simple: consider this.GetSomething(abc).DoSomething(), where GetSomething(abc) returns null. What is the object that's null? It doesn't have a name. And sometimes, especially in Release-optimized code, names for variables or other things that might be null are generated.
You should be debugging with test cases, Asserts, breakpoints, and other debug-mode code, not expecting that you can always get a good enough exception message to debug production code. E.g. even if you know that the key "dummy" was passed in, you might not have enough information to know why that key was bad, or was passed in.
Question: Why do exceptions provide less information than available?
Answer: Possible performance issues.
To produce a nice KeyNotFoundException, you need to call ToString(). This can take considerable time. For example, if I create Dictionary<StringBuilder, int>, failing to find a key would cause a (possibly huge) new memory block to be allocated and filled with data (in .NET 4.5 implementation). Furthermore, this can cause exception message to contain a few megabytes of text.
Question: Why not make exception messages more detailed in Debug mode?
Answer: Inconsistency is bad.
It is extremely difficult to fix bugs which can only be reproduced in Release mode. Getting string representation of keys only in Debug mode will cause diferent behavior:
ToString can throw exceptions.
Lazy programmers can preform checks on exception messages.
Question: But there are suggestions on UserVoice to improve the messages.
Answer: If you like them, vote for them.
I guess that meaningful NullReferenceException in a.b.c.d.e.f.g.h() chain is not top priority. It is annoying, but it has an easy workaround. If you think it is one of the most important problems, then go vote for it. But you may look around and find more interesting stuff to vote for.
In general, code which throws an exception doesn't know what's going to be done with the message. Conceptually, it might have been possible for an exception to include both Message and a DeveloperPrivateMessage properties, and specify that exceptions should refrain from placing in Message any information which could compromise security if revealed to the general public, and code receiving exceptions should refrain from persisting DeveloperPrivateMessage in any fashion which would expose it to untrusted personnel, but that would have complicated things. Instead, code that throws exceptions is expected to simply refrain from including any confidential data. Since dictionaries have no way of knowing whether keys might be used to store confidential data, that implies that keys should not be included in exception messages.
As for NullReferenceException, that's generally caught by a trap handler which may be able to determine that code was trying to execute a mov eax,[esi+8] when the ESI register was zero, but the trap handler would have no way of knowing where the value in ESI came from. If one says meh = Foo.Bar.Boom, and the Bar property returns null only after modifying Foo so that the next call won't return null, then by the time the system tries to access null.Boom, Foo.Bar won't be null. The best the system could do would be to say that "member Bar of some object was null", but that may not be very helpful.
Then you should add special handling to get this information. Remember everything comes at some cost. The more bloated you make exception handling (that shouldn't occur in the first place) - the larger the framework would have to be for every single case like this.
You really should consider these "Last chance exceptions" since you should never see them if coded correctly. Between the exception message and the stack trace that is provided - that should be enough information for your.
The responsibility of checking for null or if the key is missing is on you, the developer. The reason for this is optimization; if the default exceptions were more detailed like you would like, then the compiler would not be able to optimize as efficiently.
It's a trade-off. Adding null checks can be annoying, but it's how the language is designed.
Related
Is there a way to find out what specific object caused a NullReferenceException? I've read the page about troubleshooting NullReferenceExceptions and it talks about inspecting variables in the debugger and looking at the exception message.
What if the exception was thrown in production code so you can't run a debugger to inspect the variables? The exception message shows the stack trace so you can see what method the exception was thrown in, but it does not say which specific object was null.
I'd like to be able to add the name of the object that was null to the error message so that when I'm looking into reports from users and I come across a NullReferenceException, I can easily see what object was null and fix it. Does anyone know of a way to do this?
I also found this question which asked the same thing, but it was from 2011 and I don't know if anything has changed since then.
Edit: The question that this is flagged as a duplicate is indeed a duplicate but is also very old (2008). Has anything changed since then?
Edit 2: I found this when googling this question. Visual Studio can tell you what threw the NullReferenceException; is there any way to tap into this to add it to a log file?
It should be relatively easy to figure out given the stacktrace, but a better approach would be to include "validation" or parameters and/or null checks in your code and explicitly throw a ArgumentNullException yourself before you try to access a member of a variable that may not has been initialized. You can then supply the name of the uninitialized object:
if (obj == null)
throw new ArgumentNullException(nameof(obj));
It's a common practise to perform these checks on arguments in both constructors and methods, e.g:
public void SomeMethod(SomeType someArgument)
{
if (someArgument == null)
throw new ArgumentNullException(nameof(someArgument));
//you will never get there if someArgument is null...
var someThing = someArgument.SomeMember;
if (someThing == null)
throw new ArgumentException("SomeMember cannot be null.", nameof(someArgument));
...
}
TL;DR
The answer to your question is No, it's not possible.
The article speaks about the source code location and not the object. But much of the answer is covered in the article you shared, and if you read it fully you will know why it's not possible. For the benefit of everyone i will add the excerpt here.
Based on the available assembly metadata as of today, the runtime can infer the location of the problem and not the object.
There are no guarantees that the PDB is always there with required information to weave the IL back to a n identifier.
It's not just C#,but a bunch of other languages have to support this to make this work in the .NET runtime, which is less likely at this moment.
Assembly Metadata doesn't have debug information
Finding a name of an object during runtime requires debug information to be available, which is based on the configuration you used to build your code. There is no guarantee that the runtime can weave an address or register to a name. The assembly metadata contains the description of the Assembly , Data Types and members with their declarations and implementations, references to other types and members , Security permissions but doesn't contain source information.
Using PDB's would make it inconsistent as you don't have control over framework and library (nuget) code
I think it might not even be possible to do this consistently, Even if all compilers targeting CLR, emit enough information about identifiers (all language compilers) and the runtime consume it. The way the .NET project gets compiled won't be consistent given the fact that any .NET project that i can think of reference binaries from community / NuGet. In that case a part of the code report identifier names and the other part wouldn't.
Consider what happens to the generated types (for example IEnumerable) The runtime can figure out and report that IEnumerable.Current is null, but what is null is the underlying object in the container, which still doesn't give the answer. You walk the stack and figure out the underlying object and fix it, which is the case even without the information.
Consider multithreaded code, where you might know which object is null, but you might not know which context / call stack caused it to be null.
So my conclusion is,
we should try to infer context from methods than identifiers. Identifiers tell you what is null, but often you need to figure out why it is null because the programmer didn't anticipate it, he has to walk the stack back to figure out the issue. In case where the object is a local variable it's a programmer's error and might not have to be the runtime to figure it out.
Whenever an Exception is thrown, AppDomain.CurrentDomain.FirstChanceException is raised. You can add a handler to this event, to monitor how many exceptions are thrown, and from where during runtime. In the event handler, you have access to the actual Exception object. If a particular type of exception is of interest, you simply check the type of the Exception property on the event arguments object passed to the handler.
The following example outputs all exceptions (including inner exceptions) to a text file, including stack traces, for analysis later. Since exceptions are often caught and re-thrown, the same exception might occur multiple times in the output file, with longer and longer stack traces. Using such a file allows you to find the source of particular types of exceptions. You can also get frequency and occurrence, and other types of information from such a file.
AppDomain.CurrentDomain.FirstChanceException += (sender, e) =>
{
if (exceptionFile is null)
return;
lock (exceptionFile)
{
if (!exportExceptions || e.Exception.StackTrace.Contains("FirstChanceExceptionEventArgs"))
return;
exceptionFile.WriteLine(new string('-', 80));
exceptionFile.Write("Type: ");
if (e.Exception != null)
exceptionFile.WriteLine(e.Exception.GetType().FullName);
else
exceptionFile.WriteLine("null");
exceptionFile.Write("Time: ");
exceptionFile.WriteLine(DateTime.Now.ToString());
if (e.Exception != null)
{
LinkedList<Exception> Exceptions = new LinkedList<Exception>();
Exceptions.AddLast(e.Exception);
while (Exceptions.First != null)
{
Exception ex = Exceptions.First.Value;
Exceptions.RemoveFirst();
exceptionFile.WriteLine();
exceptionFile.WriteLine(ex.Message);
exceptionFile.WriteLine();
exceptionFile.WriteLine(ex.StackTrace);
exceptionFile.WriteLine();
if (ex is AggregateException ex2)
{
foreach (Exception ex3 in ex2.InnerExceptions)
Exceptions.AddLast(ex3);
}
else if (ex.InnerException != null)
Exceptions.AddLast(ex.InnerException);
}
}
exceptionFile.Flush();
}
};
(Example from the IoT Gateway project on GitHub, with permission).
if you think there is a possibility of getting a null pointer exception, should you use an if statement to make sure the variable is not null, or should you just catch the exception?
I don't see any difference as you can put your logic to deal with the null pointer in the if statement, or in the catch block, so which one is best practise?
I would say ALWAYS use logic to catch the exception, not try/catch.
Try/Catch should be used when you validate but some strange thing happens and something causes an error so you can handle it more gracefully.
There is no single answer that will suffice here, it depends.
Let's take a few scenarios so you can see what I mean.
Scenario: Method that takes a reference type parameter that does not accept null
You're defining a method, it takes a reference type parameter, say a stream object, and you don't want to accept null as a legal input parameter.
In this case, I would say that the contract is that null is not a valid input. If some code does in fact call that method with a null reference, the contract is broken.
This is an exception, more specifically, it's an ArgumentNullException.
Example:
public void Write(Stream stream)
{
if (stream == null)
throw new ArgumentNullException("stream");
...
I would definitely not just let the code execute until it tries to dereference the stream in this case, instead crashing with a NullReferenceException, because at that point I lost all ability to react when I know the cause.
Q. Why can't I return false instead of throwing an exception?
A. Because a return value is easy to silently ignore, do you really want your "Write" methods to just silently skip writing because you made a snafu in the calling code, passing the wrong stream object or something that cannot be written to? I wouldn't!
Scenario: Method returns a reference to an object, sometimes there is no object
In this case the contract is that null is a legal result. In my opinion, null is something to avoid because it is quite hard to make sure you handle correctly everywhere, but sometimes it is the best way.
In this case I would make sure to if my way around the result, to ensure I don't crash when the null reference comes back.
Generalisation
If you take a close look at the above two scenarios, you'll note one thing:
In both cases it comes down to what is being expected, what the contract is.
If the contract says "not null", throw an exception. Don't fall back to the old-style API way of returning false because an exceptional problem should not be silently ignored, and littering the code with if statements to ensure every method call succeeds does not make for readable code.
If the contract says "null is entirely possible", handle it with if statements.
Advertising
For getting a better grip on null problems, I would also urge you to get ReSharper for you and your team, but please note that this answer can be applied to any type of exception and error handling, the same principles applies.
With it comes attributes you can embed into your project(s) to flag these cases, and then ReSharper will highlight the code in question.
public void Write([NotNull] Stream stream)
[CanBeNull]
public SomeObject GetSomeObject()
To read more about the contract attributes that ReSharper uses, see
ReSharper NullReferenceException Analysis and Its Contracts
Contract Annotations in ReSharper 7
Well. Exceptions are just that. Exceptions. They are thrown when something unforseen has happened and should not be part of the normal program flow.
And that's what is happening here. You expected the argument to be specified when it's not. That is unexpected and you should therefore throw your own exception informing the user of that. If you want to get bonus points you can also include the reason to WHY the argument must be specified (if it's not obvious).
I've written a series of posts about exceptions: http://blog.gauffin.org/2013/04/what-is-exceptions/
From a performance standpoint it really depends what you're doing. The performance impact from a try/catch block when no exception is thrown is minimal (and if you really need that last few percent of performance, you probably should rewrite that part of your code in C++ anyway). Throwing exceptions does have a major impact on simpler operations such as string manipulation; but once you get file/database operations in the loop they're so much slower that again it becomes a trivial penalty. Throwing across an App Domain will have a non-trivial impact on just about anything though.
Performance in Operations/second:
Mode/operation Empty String File Database Complex
No exception 17,748,206 267,300 2,461 877 239
Catch without exception 15,415,757 261,456 2,476 871 236
Throw 103,456 68,952 2,236 864 236
Rethrow original 53,481 41,889 2,324 852 230
Throw across AppDomain 3,073 2,942 930 574 160
Additional test results along with the source for the tests is available from the article Performance implications of Exceptions in .NET
I would rather suggest you use if-statement for NullReference exception. For other exception, try-catch should be good enough.
The reason I suggest if-statement for NullReference exception is because C# will not tell which variable is null. if that line has more than one object could be null, you will loss track. If you are using if-statement, you can have better logging to help you get the enough information.
The main Question is if it is a good idea to have methods returning Null at all, personally i do not have any problem with this, but as soon as you try to access modifiers of an object returned from this method and you forget to check if it is assigned this becomes an issue.
Ken has a good answer about this:
If you are always expecting to find a value then throw the exception
if it is missing. The exception would mean that there was a problem.
If the value can be missing or present and both are valid for the
application logic then return a null.
See this disscussion abou tthis issue:
Returning null is usually the best idea if you intend to indicate that
no data is available.
An empty object implies data has been returned, whereas returning null
clearly indicates that nothing has been returned.
Additionally, returning a null will result in a null exception if you
attempt to access members in the object, which can be useful for
highlighting buggy code - attempting to access a member of nothing
makes no sense. Accessing members of an empty object will not fail
meaning bugs can go undiscovered.
Some further reading:
No Null Beyond Method Scope
Should We Return Null From Our Methods?
using try catch for the statements is not an good idea. because when you use try catch them it seems that if some error comes the code will not turninate the application. but if you are sure about what kind of error can come you can tap the error at that point. that will not produce any unknown errors. for example.
string name = null;
here i am going to use the name variable and i am sure that this will throw Null Refrance Error .
try
{
Console.writeLine("Name ={0}",name);
}
catch (NullRefranceException nex)
{
//handle the error
}
catch(Exception ex)
{
// handle error to prevent application being crashed.
}
This is not a good practice while you can handle this kind of error and make your code more readable. like.
if(name !=null)
Console.writeLine("Name ={0}",name);
In my experience using if is better but only if you actually expect a null reference pointer. Without any bit of code or context its difficult to say when one option is better than the other.
There's also a matter of optimization - code in try-catch blocks won't be optimized.
In general, try-catch blocks are great because they will break (move to the catch statement) whenever the exception occurs. If-else blocks rely on you predicting when the error will happen.
Also, catch blocks won't stop your code from halting when an error is hit.
Its always better to use Try Catch other than if else
Here Exceptions are two types namely handled and UN-handled exceptions
Even if u want to handle some function when the Exception u can handle it...
Handled exception always allows you to write some implementations inside the Catch block
Eg. An Alert Message, A new Function to handle when such exception occurs.
Edit 1
Updated to make the enum not an argument to the method...
Question
This type of problem comes up a lot with enums in switch statements. In the example code, the developer has accounted for all countries the program is currently using, but if another country is added to the Country enum, an exception should be thrown. My question is, what type of exception should be thrown?
Example Code:
enum Country
{
UnitedStates, Mexico,
}
public string GetCallingCode(Guid countryId){
var country = GetCountry(countryId);
switch (country)
{
case Country.UnitedStates:
return "1";
break;
case Country.Mexico:
return "52";
break;
default:
// What to throw here
break;
}
}
I've looked at
NotImplemented, The exception that is thrown when a requested method or operation is not implemented.
NotSupported There are methods that are not supported in the base class, with the expectation that these methods will be implemented in the derived classes instead. The derived class might implement only a subset of the methods from the base class, and throw NotSupportedException for the unsupported methods.
For scenarios where it is sometimes possible for the object to perform the requested operation, and the object state determines whether the operation can be performed, see InvalidOperationException.
InvalidOperation is used in cases when the failure to invoke a method is caused by reasons other than invalid arguments.
My guess is either NotImplemented or Invalid Operation. Which one should I use? Does someone have a better option (I know rolling your own is always an option)
I would go with ArgumentException, as the agrument is invalid.
EDIT: http://msdn.microsoft.com/en-us/library/system.argumentexception%28v=vs.71%29.aspx
There is also InvalidEnumArgumentException, which might more accurately describe the problem, however, I have not seen anyone use it before.
One option is to do almost a method contracts check in Debug mode. Throw in an extension method for nice looking form:
[Conditional("DEBUG")]
public static bool AssertIsValid(this System.Enum value)
{
if (!System.Enum.IsDefined(value.GetType(), value))
throw new EnumerationValueNotSupportedException(value.GetType(), value); //custom exception
}
I figured maybe only have it in debug mode so it passes your development/test environment and unit tests and in production there's no overhead (though that's up to you)
public string GetCallingCode(Guid countryId)
{
var country = GetCountry(countryId);
country.AssertIsValid(); //throws if the country is not defined
switch (country)
{
case Country.UnitedStates:
return "1";
case Country.Mexico:
return "52";
}
}
I would suggest though that this is actually the responsibility of your GetCountry method. It should recognize that the countryId is not valid and throw an exception.
Regardless, this should really be caught by your unit tests too or somehow better handled. Wherever you convert a string/int into your enum should be handled by a singular method which in turn can check/throw (just as any Parse method should) and have a unit test that checks all valid numbers.
In general, I don't think the various ArgumentExceptions (and the like) are a good candidate because there are several conditions (non-argument) cases. I think if you move the checking code to a single spot, you may as well throw your own exception that accurately communicates to any developer listening.
EDIT: Considering the discussion, I think there are two particular cases here.
Case 1: Converting underlying type to an equivalent enum
If your methods take some sort of input data (string, int, Guid?), your code performing the conversion into the enum should validate that you have an actual enum that's usable. This is the case I posted above in my answer. In such cases, likely throwing your own exception or possibly InvalidEnumArgumentException.
This should be treated pretty much like any standard input validation. Somewhere in your system you are providing garbage-in so handle it as you would any other parsing mechanism.
var country = GetCountry(countryId);
switch (country)
{
case Country.UnitedStates:
return "1";
case Country.Mexico:
return "52";
}
private Country GetCountry(Guid countryId)
{
//get country by ID
if (couldNotFindCountry)
throw new EnumerationValueNotSupportedException(.... // or InvalidEnumArgumentException
return parsedCountry;
}
EDIT: of course, the compiler requires that your method throws/returns, so not so sure what you should do here. I guess that's up to you. If that actually happens, it probably is a bone-headed exception (case 2 below) since you passed your input validation yet did not update the switch/case to handle the new value, so maybe it should throw new BoneheadedException();
Case 2: Adding a new enumeration value which is not handled by your switch/case blocks in your code
If you are the owner of your code, this falls under the "Boneheaded" exceptions described by Eric Lippert in #NominSim's answer. Though this can actually not result in an exception at all while leaving the program in an exceptional/invalid state.
The best for this is likely any place where you perform switch/case (or of the like) runs against the enumeration, you should consider writing a unit test that automatically runs the method against all defined values of your enumeration. So if you are lazy or accidentally missed a block, your unit tests will warn you that you did not update a method to account for the change in your enumeration listing.
Finally, if your enum is coming from a 3rd party which you did not realize they updated the values, you should write a quick unit test that validates all your expected values. So if you wrote your program with checks for UnitedStates and Mexico, your unit test should just be a switch/case block for those values and throw an exception otherwise warning you when/if they end up adding Canada. When that test fails after updating the 3rd party library, you know what/where you have to make changes to be compatible.
So in this "Case 2", you should throw any old exception you want since it will be handled by your unit tests just so long as it accurately communicates to you or consumers of your unit tests just what exactly is missing.
In either case, I don't think the switch/case code should be caring too much about invalid input and not throwing exceptions there. They should either be thrown at design time (via unit tests) or thrown when validating/parsing input (and therefore throw appropriate "parsing/validation" exceptions)
EDIT: I stumbled upon a post from Eric Lippert discussing how the C# compiler detects if a method with a return value ever hits its "end point" without returning. The compiler is good at guaranteeing that the end point is unreachable sometimes, but in cases as yours above, we developers know it's unreachable (except in the circumstances noted above where BoneheadedExceptions come into play).
What wasn't discussed (at least that I saw) what you should do as a developer to resolve these cases. The compiler requires that you provide a return value or throw an exception even if you know it will never reach that code. Googling hasn't magically surfaced some exception to leverage in this case (though I couldn't figure out good search terms), and I'd rather throw an exception and be informed that my assumption that it cannot reach the end is incorrect rather than returning some value which may not inform me of the problem or result in unwanted behaviour. Maybe some UnexpectedCodePathFailedToReturnValueException of some sort would be most valid in this case. When I have some time, I'll do some more digging and maybe post a question on programmers to garner some discussion.
Of the exceptions you've listed, only InvalidOperationException fits your scenario. I would consider using either this, or either ArgumentException or the more specific ArgumentOutOfRangeException since your switch value is provided as an argument.
Or, as you say, roll your own.
EDIT: Based on your updated question, I would suggest InvalidOperationException if you want to use a framework exception. However, for this more generic case, I would definitely prefer to roll my own - you can't guarantee that InvalidOperationException won't be caught elsewhere in the callstack (possibly by the framework itself!), so using your own exception type is much more robust.
I would use InvalidOperationException if the value you're working with is a product purely of your object's current state. As it says:
The exception that is thrown when a method call is invalid for the object's current state.
Even with your updated question, since the particular value you cannot deal properly with was derived from an argument passed to it, I would still use an ArgumentException - you can explain in the error message that information you're derived from the argument doesn't match anything you can deal with.
For both NotImplementedException and NotSupportedException the expectation is that, no matter what the caller does, they're not going to be able to remedy the situation. Whereas ArgumentException and InvalidOperationException are clues that, if the caller would use a different argument, or transition the object to another state (respectively), the call might work.
Personally, I don't think this is the proper place for any Exception at all. If you add a Country, you should add a case to the switch statement. The code shouldn't break because you add a value to an enum.
There is an article on when to use exceptions by Eric Lippert, that categorizes the type of exception you are looking for as: (forgive the wording it is not mine)
Boneheaded exceptions are your own darn fault, you could have prevented them and therefore they are bugs in your code. You should not catch them; doing so is hiding a bug in your code. Rather, you should write your code so that the exception cannot possibly happen in the first place, and therefore does not need to be caught.
it's impossible to pass another value, because your enum limits the possible values to the one you handle. so you don't need any exception.
Is there any behavioural difference between:
if (s == null) // s is a string
{
throw new NullReferenceException();
}
And:
try
{
Console.Writeline(s);
}
catch (NullReferenceException Ex)
{ // logic in here
}
Both throw exceptions of null object, if s is null. The first example is more readable as it shows exactly where the error occurs (the exception bit is right next to the line which will cause the exception).
I have seen this coding style a lot on various blogs by various coders of all sorts of skill levels, but why not just perform the main logic by checking if s is not null and thus save the exception from ever being raised? Is there a downside to this approach?
Thanks
No, Console.WriteLine(null) won't throw an exception. It will just print nothing out. Now assuming you meant something like:
Console.WriteLine(s.Length);
then it makes sense... and you should use the first form. Exceptions should occur when you can't predict them ahead of time with your current information. If you can easily work out that something's wrong, it makes no sense to try an operation which is bound to fail. It leads to code which is harder to understand and performs worse.
So NullReferenceException, ArgumentNullException and the like shouldn't be caught unless they're due to a nasty API which sometimes throws exceptions which you can handle, but which shouldn't really be being thrown in the first place. This is why in Code Contracts, the default behaviour for a failed contract is to throw an exception which you can't catch explicitly, other than by catching everything (which is typically somewhere at the top of the stack).
As Jon Skeet already mentioned, Console.WriteLine (null) won't throw an exception.
Next to that, I'd like to say that you should 'fail fast'. That means that you have to put 'guard' clauses in your methods, and check the arguments that have been given in your methods if they can be considered to be valid.
This allows you to throw an exception yourself, and give an additional message which will be helpfull when debugging. The message can give a clear indication on what was wrong, and that is much handier then if you're faced with a NullReferenceException that has been thrown without any good information in it's message property.
If you are writing a class library there may be occasions when you know that if a certain parameter contains a null value, that may cause trouble further down the line. In those cases I usually find it to be a good idea to throw an exception (even though I would probably use ArgumentNullException for that case) to make the user of the class library aware of this as early and clearly as possible.
Exceptions are not always a bad thing.
Jon Skeet is right but, more generally, it's all a question of semantic.
If the situation has some applicative meaning (number out of bound, date of birth in the future, etc) you may want to test for it before doing any operation and throw a custom exception (that is one with meaning for your application).
If the situation is truly "exceptional", just write the code as if the given value were correct. See, if you put the test, you will do it everytime, knowing that the VM will do it anyway in case it needs to throw an exception. From a performance point of view, if the error happens to have a statistically small occurence, it makes no sense.
If you're taking a Design By Contract type approach to things then a piece of code can specify that it throws exceptions in order to specify its contract and to enforce it. The other half is, of course, calling code recognising the contract and fulfilling it.
In this case it would mean that if you know a method will throw an exception if you pass in null (i.e. its contract is that you don't pass nulls) then you should check before calling it.
Jon Skeet says that the method won't throw an exception anyway. That may or may not be true but the principle of guarding for method contract stands (which I believe was the point of your question).
I am confused. Whether to create a custom exception or .Net base class library has the relevant exception?
I am calling some kind of service or framework API and it returns back a null reference which is an exceptional case for my tier. I know that the system won't be able to proceed with null reference and I should get a NullReferenceException down the line if I proceed.
So, should I create a custom exception at that point or should I wait to occur the NullPointerReference?
See the code snippet below
Organization organization = OrganizationService.GetOrganizationById("123");
this.SetOrders(organization.Id); // This will give me NullReferenceException
please guide me.
Thanks and regards
123Developer
In general, its good practice to catch errors as soon as possible and handle them in the best manner possible - either by using default values to work around the error, or informing the user that you cannot proceed.
So in this specific case, if i understand correctly, i would test the variable for null, and if its null do not continue - bail out gracefully.
NullPointerReference exceptions are always hard to debug and should be avoided whenever possible. In certain cases you could use ArgumentNullException, if the "null" value is one of the passed parameters. Not in your case though and that's where I would recommend a custom exception.
Throw an InvalidOperationException if it has nothing to do with any arguments passed to your method, or an ArgumentException otherwise. Do this as soon as is reasonably possible, to avoid accidentally corrupting your state.
Aside from anything else, this allows you to give a more useful message, indicating what couldn't be found.
as a general rule you should only catch exceptions down the stack if you can add meaning to the exception itself.
In your particular case, I would suggest that you check the value for null, and throw an appropriate exception yourself (possibly an InvalidOperationException with a message of "Organization not found"?)
I often design a DataNotFoundException that is thrown when a get-operation based on an object ID fails. My rationale for doing so is that ID's are typically not entered by the user, but used only in the code, so if a search is performed using a non-existing ID the input is bad, and I want to signal that in a clear manner.