Related
I came across this MSDN page that states:
Do not throw Exception, SystemException, NullReferenceException, or IndexOutOfRangeException intentionally from your own source code.
Unfortunately, it does not bother to explain why. I can guess the reasons but I hope that someone more authoritative on the subject might offer their insight.
The first two make some obvious sense, but the latter two seem like ones you would want to employ (and in fact, I have).
Further, are these the only exceptions one should avoid? If there are others, what are they and why should they, too, be avoided?
Exception is the base type for all exceptions, and as such terribly unspecific. You shouldn’t ever throw this exception because it simply does not contain any useful information. Calling code catching for exceptions couldn’t disambiguate the intentionally thrown exception (from your logic) from other system exceptions that are entirely undesired and point out real faults.
The same reason also applies to SystemException. If you look at the list of derived types, you can see a huge number of other exceptions with very different semantics.
NullReferenceException and IndexOutOfRangeException are of a different kind. Now these are very specific exceptions, so throwing them could be fine. However, you still won’t want to throw these, as they usually mean that there are some actual mistakes in your logic. For example the null reference exception means that you are trying to access a member of an object which is null. If that’s a possibility in your code, then you should always explicitly check for null and throw a more useful exception instead (for example ArgumentNullException). Similarly, IndexOutOfRangeExceptions occur when you access an invalid index (on arrays—not lists). You should always make sure that you don’t do that in the first place and check the boundaries of e.g. an array first.
There are a few other exceptions like those two, for example InvalidCastException or DivideByZeroException, which are thrown for specific faults in your code and usually mean that you are doing something wrong or you are not checking for some invalid values first. By throwing them knowingly from your code, you are just making it harder for the calling code to determine whether they were thrown due some fault in the code, or just because you decided to reuse them for something in your implementation.
Of course, there are some exceptions (hah) to these rules. If you are building something that may cause an exception which exactly matches an existing one, then feel free to use that, especially if you are trying to match some built-in behavior. Just make sure you choose a very specific exception type then.
In general though, unless you find a (specific) exception that fills your need, you should always consider creating your own exception types for specific expected exceptions. Especially when you are writing library code, this can be very useful to separate the exception sources.
I suspect the intent with the last 2 is to prevent confusion with inbuilt exceptions that have an expected meaning. However, I'm of the opinion that if you are preserving the exact intent of the exception: it is the correct one to throw. For example, if you are writing a custom collection, it seems entirely reasonable to use IndexOutOfRangeException - clearer and more specific, IMO, than ArgumentOutOfRangeException. And while List<T> might choose the latter, there are at least 41 places (courtesy of reflector) in the BCL (not including arrays) that throw bespoke IndexOutOfRangeException - none of which are "low level" enough to deserve special exemption. So yeah, I think you can justly argue that that guideline is silly. Likewise, NullReferenceException is kinda useful in extension methods - if you want to preserve the semantic that:
obj.SomeMethod(); // this is actually an extension method
throws a NullReferenceException when obj is null.
As you point out, in the article Creating and Throwing Exceptions (C# Programmming Guide) under the topic Things to Avoid When Throwing Exceptions, Microsoft does indeed list System.IndexOutOfRangeException as an exception type that should not be thrown intentionally from your own source code.
In contrast, however, in the article throw (C# Reference), Microsoft seems to violate its own guidelines. Here is a method that Microsoft included in its example:
static int GetNumber(int index)
{
int[] nums = { 300, 600, 900 };
if (index > nums.Length)
{
throw new IndexOutOfRangeException();
}
return nums[index];
}
So, Microsoft itself isn't being consistent as it demonstrates the throwing of IndexOutOfRangeException in its documentation for throw!
This leads me to believe that at least for the case of IndexOutOfRangeException, there may be occasions where that exception type can be thrown by the programmer and be considered an acceptable practice.
When I read your question, I asked myself under what conditions one would want to throw the exception types NullReferenceException, InvalidCastException or ArgumentOutOfRangeException.
In my opinion, when encountering one of those exception types, I (the developer) feel concerned by the warning in the sense that the compiler is talking to me. So, allowing you (the developer) to throw such exception types is equivalent to (the compiler) selling the responsibility. For instance, this suggests the compiler should now allow the developer to decide whether an object is null. But making such a determination should really be the job of the compiler.
PS: Since 2003 I have been developing my own exceptions so I can throw them as I wish. I think it is considered a best practice to do so.
Putting the discussion about NullReferenceException and IndexOutOfBoundsException aside:
What about catching and throwing System.Exception. I've thrown this type of exception in my code a lot and I was never screwed by it. Similarly, very often I catch the unspecific Exception type, and it also worked pretty well for me. So, why is that?
Usually users argue, that they should be able to distinguish error causes. From my experience, there are just a very few situations where you would want to handle different exception types differently. For those cases, where you expect users to handle errors programmatically, you should throw a more specific exception type. For other cases, I'm not convinced by the general best practice guideline.
So, regarding throwing Exception I don't see a reason to prohibit this in all cases.
EDIT: also from the MSDN page:
Exceptions should not be used to change the flow of a program as part of ordinary execution. Exceptions should only be used to report and handle error conditions.
Overdoing catch clauses with individual logic for different exception types are not best practice, either.
It's often said that you shouldn't use exceptions for regular error handling because of bad performance. My guess is that that bad performance is caused by having to instantiate a new exception object, generate a stack trace, etc. So why not have lightweight exceptions? Code like this is logically sound:
string ageDescription = "Five years old";
try {
int age = int.Parse(ageDescription);
}
catch (Exception) {
// Couldn't parse age; handle parse failure
}
And yet we're recommended to use TryParse instead to avoid the overhead of the exception. But if the exception were just a static object that got initialized when the thread started, all the code throwing the exception would need to do is set an error code number and maybe an error string. No stack trace, no new object instantiation. It would be a "lightweight exception", and so the overhead for using exceptions would be greatly reduced. Why don't we have such lightweight exceptions?
The exception object instantiation is the smallest problem in the whole case. The real performance killer is that the control flow must stop executing your program and has to look up the call stack for possible handlers (catch blocks) that can catch the thrown exception, then it has to execute the correct ones (and their finally blocks), rethrow exceptions when told so and then continue executing the program on the right place, i.e. after the last handler. Your idea of "lightweight" exceptions would change nothing of this, it would even slow down creation of threads, because it would have to create and store the exception object, and would prevent exception filtering by type, which is now possible.
By using TryParse, you avoid all this by a simple conditional clause, also you actually write less code and it is much easier to read and reason about.
Exceptions are for exceptional cases and in such scenarios, they provide lots of useful information for logs/debugger.
The performance hit isn't just because you're creating a new Exception object. A lot of it has to do with the conditional unwinding of the stack that needs to be done when an exception occurs.
For example, think about the work that would have to be done when you have exception handlers that catch different kinds of exceptions. At each point in the stack, as it's unwound from callee to caller, the language must do a type check to see not only if the exception can be handled, but what the most appropriate handler is. That's a significant amount of overhead in its own right.
If you really want to be lightweight, you should return a result from your functions -- that's what Int32.TryParse() does. No stack unwinding, no type checking, just a simple condition which can easily be optimized for.
EDIT: One somewhat interesting thing to note is that C# was created after Java. Java has a couple of interesting constructs which cause exception handling to be more complicated than what we see in C#, namely checked exceptions and the throws keyword. Kind of interesting reads. I'm (personally) glad that C# didn't include this "feature". My guess is that they bifurcated their exception handlers to boost performance. In the real world, as I understand it, a LOT of developers just end up specifying throws exception in their function declarations.
You should use int.TryParse in your case. And it is faster and more readable to test some conditions then to throw and catch exception. Use exceptions for exceptional situations not for regular validation.
The problem with exceptions isn't just generating the exception itself, that's honestly not even the most time consuming part. When you throw an exception (after it has been created) it needs to unwind the stack going through each scope level, determining if that scope is a try/catch block that would catch this exception, update the exception to indicate it went through that section of the stack, and then tearing down that section of the stack. And then of course there are all of the finally blocks that may need to be executed. Making the Exception itself store less information wouldn't really simplify any of that.
Because the utility offered by the "heavyweight" exceptions is exceptionally (ha ha) useful. I can't tell you how often I've wanted the ability to dump something like a stack trace in C land without having to ask people to yank out a debugger.
Generating things like the stack trace after the fact (i.e. after the exception has been caught on demand) are infeasible because once the exception has been caught, the stack has been unwound -- the information is gone. You want information about the point of failure; so the data must be collected at the point of failure.
As for the "new object instantiation" -- that is so cheap in comparison to other expensive exception features (unwinding the stack, stack trace, multiple function exit points, etc.) that it isn't worth worrying about.
You're not recommended to use TryParse instead of Parse because of performance. If there's any chance a parse can fail (because it's user generated input for example) then the failure to parse is not exceptional, it's to be expected. As the name implies, exceptions are for exceptional circumstances. For stuff that should have been caught earlier, but wasn't, so unexpected that you can't really continue.
If a function expects an object but instead null is passed in, then it's up to the designer of the method what the right thing to do is in this case. If the parameter is an optional override for a default, the program ca continue and use the default or ignore the parameter. But otherwise, the program should simply throw a ArgumentNullException.
Performance shouldn't be a consideration at all when deciding to use exceptions or not. It's a matter of intent and purpose. They're not even that slow, sure they're many times slower than adding two integers, but I can still throw 50,000 exceptions per second on my aging Core 2 Duo. If the use of exceptions ever becomes a bottleneck, you're not using them in the right way.
My understanding is based on this long, but fantastic, article which supports the behavior listed in the C# specification.
The CLI standard (EMCA-335) shows that if there is no suitable catch, the runtime should terminate immediately. The .NET runtime does not do this, instead it seems to lean toward the behavior of the C# specification (EMCA-334).
First, I find it strange that a language specification is appears to be defining framework behavior. Secondly, They seem to contradict.
Do they contradict each other, or am I getting the wrong meaning of the document?
Does a runtime have to go about exception handling in this way to be compliant with the standard?
As an optional question, which one is the "correct" one, as in, if I were to write my own implementation of the CLI which one should I use? Note that EMCA-335 (CLI) document was updated two months ago, where EMCA-334 (C#) was updated back in 2006.
ECMA-335 Partition I Section 12.4.2.5
When an exception occurs, the CLI searches the array for the first protected block that
Protects a region including the current instruction pointer and
Is a catch handler block and
Whose filter wishes to handle the exception
If a match is not found in the current method, the calling method is searched, and so on. If no match is found the CLI will dump a stack trace and abort the program.
If a match is found, the CLI walks the stack back to the point just located, but this time calling the finally and fault handlers. It then starts the corresponding exception handler.
C# Specification §15.9.5 and §15.10 (§8.9.5 and §8.10 on MSDN)
The main difference between it and the CLI standard, is that whether or not a catch block is found, the application will not just exist, but will still unwind the stack, and take care of finally handlers.
I would suggest reading the standard itself to get a better meaning of this, since below is a very crude summary. It outlines step-by-step how a try statement is executed with each possible scenario.
In the function that raises the exception:
Looks for a matching catch clause in each try statement
Executes the catch statement if it exists
A finally block is executed if it exists
If there was no handler, the above steps are repeated in the calling function
If the exception processing terminates all function member invocations in the current thread, indicating that the thread has no handler for the exception, then the thread is itself terminated. The impact of such termination is implementation-defined.
There's no conflict here. The C# language specification is worded like this:
If the try statement has no catch clauses or if no catch clause matches the exception:
• If the try statement has a finally block, the finally block is executed.
• The exception is propagated to the next enclosing try statement.
Bullet 2 here specially doesn't say what happens when there is no next enclosing try statement. For that, turn to the end of 8.9.5:
If the exception processing terminates all function member invocations in the current thread, indicating that the thread has no handler for the exception, then the thread is itself terminated. The impact of such termination is implementation-defined.
It certainly is implementation-defined. Beyond the Ecma 335 spec, the exception handling policy is a configurable item in the Microsoft CLR. Controlled by ICLRPolicyManager::SetActionOnFailure(). In turn configurable in the default host with the <legacyUnhandledExceptionPolicy> app.exe.config file element. The default for CLR version 2.0 and up is to immediately terminate the program.
This is otherwise fairly unproductive biblical hermeneutics. None of this should come as a surprise to a C# programmer, especially given how easy it is to test.
I think this might just be a matter of a vague wording.
If a match is not found in the current method, the calling method is searched, and so on. If no match is found the CLI will dump a stack trace and abort the program.
Okay, that's true in C#. We all know that if we don't have a catch then an exception will bring down our program.
If a match is found, the CLI walks the stack back to the point just located, but this time calling the finally and fault handlers. It then starts the corresponding exception handler.
And that matches what we know from C# too. If there are some finally (we don't get to see fault) blocks to deal with as we go up the stack from the exception being thrown until our catch block, they get processed, but it stops there and goes no further up the stack.
A lot hangs on how we read the "If" that starts that second excerpt I just quoted. You're reading it as "if ... then ... otherwise no such thing". It could be read though as the first excerpt identifying the point in the stack that will be walked to: If there was a catch, then it's walked to that point. If there is no catch, then it's walked to the very top of the stack and we get a dump and abort. The finally handlers (and fault handlers) still get called, but the point is not that of a matching catch handler.
Your reading is the most literal, and mine the one that stretches things a bit. However, mine does match with the description of finally elsewhere in the same standard, most closely
The cited article in the O.P. has an incorrect underlying assumption:
Of course, we can’t talk about managed exceptions without first considering Windows
Structured Exception Handling (SEH). And we also need to look at the C++ exception
model. That’s because both managed exceptions and C++ exceptions are implemented
on top of the underlying SEH mechanism, and because managed exceptions must
interoperate with both SEH and C++ exceptions.
The CLR standard (ISO 23271/ECMA 335) is intentionally platform-agnostic. Microsoft's implementation is one of many possible implementations (Mono, of course, being another).
Interoperability with Windows Structured Exception Handling and C++ exception handling is, I'm pretty sure, Microsoft's choice and not an ISO 23271 requirement.
My exception handling skills are very primary and I am always very confused about the way I should use them, not so much of the how/syntax. I am currently using C# (if there would be different things applicable to it).
My question is that what are the benefits of creating your own Exception class while developing an application? In comparison to throwing a standard Exception class exception. Basically what is a healthy practice of exceptions in your application.
Or if not benefits, then disadvantages?
By creating your own exceptions you can often create a more meaningful message (or more application specific type of message) for the end user, while still wrapping the original message, so as not to lose any useful information.
There is a great book by Bill Wagner that covers some reasoning about when you should or should not create your own exceptions along with some good practices for exception handling in general. Here is a small excerpt:
Your application will throw exceptions -- hopefully not often, but it
will happen. If you don't do anything specifc, your application will
generate the default .NET Framework exceptions whenever something goes
wrong in the methods you call on the core framework. Providing more
detailed information will go a long way to enabling you and your users
to diagnose and possibly correct errors in the field. You create
different exception classes when different corrective actions are
possible and only when different actions are possible. You create
full-featured exception classes by providing all the constructors that
the base exception class supports. You use the InnerException property
to carry along all the error information generated by lower-level
error conditions.
If there is a specific type of problem unique to your application that will call for a unique recovery strategy at a higher level in your application, you should create your own exception type so you can recognize and recover from that sort of problem optimally.
If the error is more of a "the caller did something wrong" variety, use the standard exception classes.
If you think your library is going to be long-lived and valuable, I would err on the side of creating your own exception classes, so that future users of your library can fashion their own recovery strategy.
Sometimes you want to do diffrent things for diffrent types of error, for example if a user inputs bad data it dosent make sence to crash the whole application and email the administrator. It would make sence to do that for a more serious exeption such as a stack overflow. You would then impliment diffrent catches depending on the type of error.
If a method is documented as throwing some particular class of exception in some particular circumstance, it should ensure that there's no way any exception of the class can bubble up through it in other circumstances. In many cases, the most practical way to ensure this may be to create a custom exception class.
Actually, I would regard much of the exception hierarchy as being pretty useless, and would suggest focusing on a fairly small number of exceptions, from which nearly all good exceptions should derive.
CleanFailureException -- The indicated operation could not be performed for some reason, but has not altered any object's state. There is no reason to believe any object's state is corrupt except to the extent implied by the operation's failure. This should be the type of exception thrown by a DoSomething method if a TrySomething method would return False. May in some cases be wrapped in a more severe instruction, if a failed operation leaves one or more objects in partially-altered or inconsistent states.
StateDisturbedException -- The indicated operation could not be completely performed for some reason, but may have been partially performed. The object on which an action was being performed has a state which complies with its own invariants, but may or may not comply with caller's expectations of it. Caller may attempt to use the object only after examining it and making sure it complies with expectations (changing it as needed). Alternatively, this exception should be caught at the point where the target object would no longer exist, and then wrapped in a CleanFailureException.
TargetStateCorruptException -- The indicated operation could not be performed because the particular object being acted upon is corrupt, but there is no particular reason to expect that corruption extends outside the object. This exception should be caught at the point where the target object would no longer exist, and then wrapped and replaced with CleanFailureException.
ParentStateCorruptException -- The indicated operation could not be performed because some object which the target's documentation would regard as a "parent" object is corrupt. Catch at the level where the corrupt parent objects would no longer exist, then wrap in a "CleanFailureException".
SystemOnFireException
While it may be nice to have exception names that indicate the nature of what went wrong, from a catching perspective what matters is whether one can safely catch and resume. Any exception hierarchy should focus on the latter issues, rather than the former. If the goal is to inform people of what went wrong, that should be done in Exception.Message.
The main benefits are to add information, so exceptions are more meaningful and thus allowing to catch exceptions that are specific to your application.
Throwing an exception is actually a more expensive operation than quietly failing, such as returning a bool. This question highlights what I mean:
How much more expensive is an Exception than a return value?
If you're writing something that you anticipate other developers are going to be using in their own project, then sure, an exception could be useful for them to make sure they're using your code right. Otherwise, if you're just using it within your own codebase, I would make sure to quietly fail.
One example where custom exceptions work well is when you are expecting external applications to interface with your project.
For example, if you had a small project that sends out an email it might make sense to throw a custom 'TooFewRecipients' error if you had a hard limit on the minimum number of recipients that must be emailed.
Custom exceptions will in general inherit from System.Exception
Remember that Exceptions should only be used for exceptional cases which your project can't handle in any other way, and they should be understandable enough to aid a 3rd party developer understand the issue. There is more information at MSDN
I've been writing a lot of code recently that involves interop with the Win32 API and have been starting to wonder what's the best way to deal with native (unmanaged) errors that are caused by calls to Windows API functions.
Currently, the calls to native functions look something like this:
// NativeFunction returns true when successful and false when an error
// occurred. When an error occurs, the MSDN docs usually tell you that the
// error code can be discovered by calling GetLastError (as long as the
// SetLastError flag has been set in the DllImport attribute).
// Marshal.GetLastWin32Error is the equivalent managed function, it seems.
if (!WinApi.NativeFunction(param1, param2, param3))
throw new Win32Exception();
The line that raises the exception can be equivalently rewritten as such I believe:
throw new Win32Exception(Marshal.GetLastWin32Error());
Now, this is all well in that it throws an exception appropriately containing the Win32 error code that was set as well as a (generally) human-readable description of the error as the Message property of the Exception object. However, I have been thinking that it would be advisable to modify/wrap at least some, if not all, of these exceptions so that they give a slightly more context-oriented error message, i.e. one more meaningful in whatever situation the native code is being used. I have considered several alternatives for this:
Specifying a custom error message in the constructor for Win32Exception.
throw new Win32Exception(Marshal.GetLastWin32Error(), "My custom error message.");
Wrapping the Win32Exception in another Exception object so that both the original error code and message are retained (the Win32Exception is now the InnerException of the parent exception).
throw new Exception("My custom error message.",
Win32Exception(Marshal.GetLastWin32Error()));
The same as 2, except using another Win32Exception as the wrapper exception.
The same as 2, except using a custom class derived from Exception as the wrapper exception.
The same as 2, except using a BCL (Base Class Library) exception as the parent when appropiate. Not sure whether it's even appropiate to set the InnerException to the Win32Exception in this case (perhaps for a low-level wrapper but not a higher-level/abstracted interface that doesn't make it obvious that Win32 interop is happening behind the scenes?)
Essentially what I want to know is: what is the recommended practice on dealing with Win32 errors in .NET? I see it done in open-source code in all sorts of different ways, but I was curious whether there were any design guidelines. If not, I'd be interested in your personal preferences here. (Perhaps you even use none of the above methods?)
This isn't really specific to Win32 exceptions; the question is, when should two different error cases be identified by two different Exception-derived types, and when should they throw the same type with different values stored inside it?
Unfortunately this is impossible to answer without knowing in advance all the situations your code will be called in. :) This is the problem with only being able to filter exceptions by type. Broadly speaking, if you have a strong feeling that it would be useful to treat two error cases differently, throw different types.
Otherwise, it is frequently the case that the string returned by Exception.Message just needs to be logged or displayed to the user.
If there is additional information, wrap the Win32Exception with something more high-level of your own. For example, you're trying to do something to a file, and the user you're running under doesn't have permission to do it. Catch the Win32Exception, wrap it in an exception class of your own, whose message gives the filename and the operation being attempted, followed by the inner exception's message.
My view has always been that the appropriate way to handle this depends on the target audience and how your class is going to be used.
If the caller of your class/method is going to realize that they are calling into Win32 in one form or another, I would use option 1) you have specified. This seems the most "clear" to me. (However, if this is the case, I'd name your class in a manner that makes it clear that the Win32 API is going to be used directly). That being said, there are exceptions in the BCL that actually subclass Win32Exception to be more clear, instead of just wrapping it. For example, SocketException derives from Win32Exception. I've never personally used that approach, but it does seem like a potentially clean way to handle this.
If the caller of your class is going to have no idea that you're calling into the Win32 API directly, I would handle the exception, and use a custom, more descriptive exception you define. For example, if I'm using your class, and there's no indication that you're using the Win32 api (since you're using it internally for some specific, non-obvious reason), I would have no reason to suspect that I may need to handle a Win32Exception. You could always document this, but it seems more reasonable to me to trap it and give an exception that would have more meaning in your specific business context. In this case, I might wrap the initial Win32Exception as an inner exception (ie: your case 4), but depending on what caused the internal exception, I might not.
Also, there are many times when a Win32Exception would be thrown from a native call, but there are other exceptions in the BCL that are more relevant. This is the case when you're calling into a native API that isn't wrapped, but there are similar functions that ARE wrapped in the BCL. In that case, I would probably trap the exception, make sure that it is what I'm expecting, but then throw the standard, BCL exception in its place. A good example of this would be to use SecurityException instead of throwing a Win32Exception.
In general, though, I would avoid option 2 and 3 you listed.
Option two throws a general Exception type - I would pretty much recommend avoiding that entirely. It seems unreasonable to wrap a specific exception into a more generalized one.
Option three seems redundant - There's really no advantage over Option 1.
Personally I would do #2 or #4...Preferably #4. Wrap Win32Exception inside your exception which is context sensitive. Like this:
void ReadFile()
{
if (!WinApi.NativeFunction(param1, param2, param3))
throw MyReadFileException("Couldn't read file", new Win32Exception());
}
This way if somebody catches the exception, they will have a pretty good idea where the problem occurred. I wouldn't do #1 because it requires the catch to interpret your text error message. And #3 doesn't really give any additional information.