I've read that throwing exceptions is an expensive operation. However, doesn't creating your own exceptions make your code more expressive and readable?
Some of my coworkers suggest that you should just use System.Exception and insert your custom text into the message instead of creating a new custom exception.
I'm interested in other opinions. Appreciate any suggestions.
Do not throw System.Exception. Ever.
The problem with it resides in the calling code. It is a bad practice to catch the general Exception object for many reasons. If you throw an instance of the Exception base class, then calling code has no choice but to catch Exception if they want to handle it. This forces the calling code to use a bad practice.
Also, the calling code has no reliable means of distinguishing what the exception was, if all it gets is Exception.
It is typically best to use one of the pre-defined exceptions if any are applicable (ArgumentException, InvalidOperationException, etc.). If none correctly describe the situation, then a custom exception class is a perfectly good way to go.
It's the overhead of throwing an exception itself (creating the object, walking the stack, etc.) that's costly. Making your own exception class adds almost no overhead, so if you're going to throw an exception, don't make it new Exception("message")!
Exceptions aren't meant to be read by people (though their messages and stack traces are read by people), they're meant to be read by code. If there's something your code can do in response to a custom exception, by all means go for it. But the exception is just destined to be logged, there's no point to making a custom one.
The overhead of custom exceptions is that they're another thing to maintain and test. If an existing exception is suitable, use that instead. (E.g., ArgumentNullException instead of ZipCodeNullException.)
If there's any reason for your exception to be caught and handled differently from standard Exceptions, then you should create your own class.
If there's any reason for your exception to take different arguments (e.g. to produce a specially-formatted message based on a set of arguments that you're often likely to have), then you should create your own class.
In any other case, you're safe just using Exception. Generally speaking, it doesn't really cost any more to instantiate or throw a custom exception than a standard one, at least not compared with the expense of throwing an exception in the first place. Exceptions, by definition, should be exceptional, and therefore performance during the throwing of an exception is a non-issue. The point is to have all the information you need when the time comes to look at why that exception was thrown.
You should never throw a System.Exception, because then the only way to catch is is by catch(System.Exception). It's very bad practice to catch a blanket exception like that. You should catch specific exceptions, which give you a way to properly handle it without crashing the software. By generating custom exceptions, you give yourself a way to potentially recognize and recover from them.
For example, if your code means to open a file, and you get an unknown exception, how do you recover from it? However, if you catch a specific File Not Found exception, that is much easier to recover from. You can tell the user definitively that the file doesn't exist.
I don't see a reason to believe that custom exceptions are any more expensive than the built-in ones.
"Expensive" is a relative term and - as the name already suggests - an exception should be an exception, so it will probably not affect the performance of your code. The cost of throwing an exception is - as far as I know - independent of the type of the exception, so you should not restrict yourself to System.Exception.
But most important: http://c2.com/cgi/wiki?PrematureOptimization
I prefer to use the most appropriate built in exception, and if that doesn't already exist, derive my own from System.ApplicationException.
I wouldn't recommend throwing System.Exception with a custom message.
Your coworker is talking nonsense. Throwing an exception is the same cost regardless of the class.
And to be honest, all this talk of "expensive" exceptions - yes they are more expensive than a null check or some such, so don't ever use them as a replacement for some sanity check, but they should be encouraged where they make sense (like IOException for example, that's an excellent use case for them - problems with I/O are an exceptional case and they usually must be handled outside of normal program flow).
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.
I've dealt with instances where I would throw/rethrow an exception knowing that the code surrounding it would catch the specific exception. But is there any time you would want to throw an exception, knowing that it wouldn't be caught?
Or at least, NOT catch an exception?
Exceptions immediately halt the application unless their handled right? So I guess I'm asking if you would ever want to purposely let your application die?
If your application is primarily going to be used by other clients and is not standalone, it generally makes sense to throw exceptions if a condition arises that you don't know how to (or don't want to) handle, and there's no sensible way for you to recover from it. Clients should be able to decide how they want to handle any exceptions that you might throw.
On the other hand, if your application is the endpoint, throwing an exception essentially becomes a notification mechanism to alert people that something has gone terribly wrong. In such cases, you need to consider a few things:
How important is the continued running of the application? Is this error really unrecoverable? Throwing an exception and terminating your program is not something you want to be doing on the space shuttle.
Are you using exceptions as a proxy for real logging? There's almost never a reason to do this; consider a real logging mechanism instead. Catch the exception and have the logger work out what happened.
What are you trying to convey by throwing the exception yourself? Ask yourself what the value in throwing a new exception is, and consider carefully whether there isn't a better way to do what you want.
Not catching an exception may leave resources in a bad state. If you don't gracefully exit, things are generally not cleaned up for you. Make sure you understand what you're doing if you need to do this -- and if you're not going to catch it, at least consider a try-finally block so you can do some tidying up.
There's a very good rule that I came across a while ago:
Throw an exception when a method can't do what its name says it does.
The idea is that an exception indicates that something has gone wrong. When you are implementing a method, it is not your responsibility to be aware of whether it will be used correctly or not. Whether the code using your method catches the exception or not is not your responsibility, but the responsibility of the person using your method.
Another rule to follow is:
Don't catch an exception unless you know what you want to do with it.
Obviously, you should include cleanup code in a try...finally block, but you should never just catch an exception just for the sake of catching it. And you should never swallow exceptions silently. While there are occasions when you may want to catch all exceptions (e.g. by doing catch (Exception ex) in C#), these are fairly uncommon and generally have a very specific technical reason. For example, when you are using threads in .NET 2.0 or later, if an exception escapes from your thread, it will cause the entire application domain to unload. In these cases, however, at the very minimum you should log the exception details as an error and provide an explanation in the comments.
Sure. For example, if you're trying to load some bytes into a string in Java:
try {
String myString = new String(byteArray, "UTF-8");
} catch (UnsupportedEncodingException e) {
// Platform doesn't support UTF-8? What is this, 1991?
throw new RuntimeExceptione(e);
}
In this case, there is no graceful degradation, the platform simply can't support the operation desired. You can check for this condition at initialization all you want, but the constructor for String still throws this exception, and you have to deal with it. Either that, or use Charset.forName() :)
Generally, and certainly in early iterations of your application, don't catch the exception. More often than not, the recovery from an exception will require a business rule of some sort, and, more often than not, those business rules are not defined for you. If you "handle" the exception instead of letting the application die then you will most likely be inventing business rules for your customer. Not good.
The general pattern of catching every exception just for the sake of catching it has caused me more headaches than I can count. It usually happens that someone puts some sort of generic exception handling code throughout the application, which inevitably ends up hiding a bug or creating some behavior that is unwanted. (incidentally, catching and then not rethrowing is even worse.)
So, I'd suggest that you ask instead: "When should I catch an exception?"
Here's the thing ... it is about "layers", or "encapsulation", or "low coupling". At some place in your codebase, you're writing a method to do something. Say it's a public method. Therefore, it should not assume much or anything about the caller ... rather, it should merely do the job it is supposed to do, regardless of who is calling it and what context the caller is in.
And if, for some reason, it cannot complete its job, then it needs to tell the caller "Sorry, I couldn't do that, and here's why". Exceptions are an excellent mechanism to let it tell the caller that (not the only mechanism, but the best mechanism I've ever seen for most cases).
So, when you throw the exception, you have no idea whether it will be caught or not ... because you're exposing a public method and you have no idea who might choose to call it and why.
The catching of the exception is the job of the "context". For example, say you're writing a library with public methods that might throw exceptions. Then, say you're using that library from a Windows Forms app. The Windows Forms app might catch exceptions and show a message box to the user.
But later, you might use the same library from a Windows Service. The Service would be more likely to catch the exception, log it, return an error to the original caller, but keep running so it can process further requests.
So the exception is like a contractual agreement between the caller and the provider. The provider says, "I'll either do the job or tell you why I can't. What you do from there is your own business." And the caller says, "OK, if you can't do the job, just tell me why, and I'll decide what to do in that case."
But is there any time you would want to throw an exception, knowing that it wouldn't be caught?
I would say that if you're manually throwing an exception, most of the time you don't know if it will be caught. If you knew it would be caught you could just handle it yourself rather than throwing the exception in the first place.
To be fair, I suppose that depends in part on the kind of programming you're doing, and sometimes the same programmer ends up building both the library and the code that consumes said library.
Would you ever NOT catch an exception?
If you didn't expect/weren't aware an exception could be thrown. But putting that aside and assuming you are aware of the exception, sometimes you know about it at one tier but know the next tier up is the more appropriate place to handle it.
It depends on the type of application. Web applications can continue running even after exceptions have bubbled up to the execution context.
It is common practice to 'throw/rethrow' an exception if you catch the exception at a level where it can't be dealt with. But, you would almost always add context to the issue, at the very least add some logging at the higher level to say that it was caught and rethrown.
for example
A calls B calls C (throws exception)
B catches/rethrows
A catches.
In this case, you would want B to add some logging so that you can differentiate between B generating and throwing an error, and C generating and throwing an error. That would allow you a greater ability to debug and fix problems later.
In general you will almost NEVER want an exception to kill your program. The best practice is to catch the except and exit gracefully. This allows you to save any currently open information and release resources that are being used so they don't become corrupted. If you intend to exit, you can create your own 'core-dump' information report that includes the things you were doing when you caught the fatal exception.
If you let the exception kill your process you are eliminating your chance to get custom tailored crash information, and you are also skipping the part where you provide the user with a friendly error message and then exit.
So, I would recommend ALWAYS catching exceptions, and never voluntarily letting them run amok in your program.
EDIT
If you are writing a library, you have to choose ahead of time whether your function will throw an exception, or be exception safe. In those cases, sometimes you will throw an exception and have no idea if the calling party will catch it. But in that case, catching it is not your responsibility, as long as the api declares that the function could throw exceptions.
(I'm looking for a word that means 'could possibly throw exception'... anyone know what it is? It's going to bug me all day.)
Firstly, there absolutely are situations where it is better to not catch an exception.
Sometimes, an exception can sometimes tell you that your program is in an unknown state. There are a number of exceptions where this is pretty much intrinsically true given the exception type. A NullReferenceException essentially tells you "there is a bug". And by catching such an exception, you may hide the bug, which sounds good in the short term, but in the long term you'd be happier to fix it. The product may not crash, but it certainly won't have the expected behaviour.
But this is also true for exception types we invent for ourselves. Sometimes, the fact that exception A has been thrown should be "impossible" - and yet it has happened, so there's a bug.
Also, something very important happens when you catch an exception: the finally blocks for the whole call stack inside the try block (and anything it calls) will be executed. What do those finally blocks do? Well, anything. And if the program is in an unknown state, I really do mean anything. They could erase valuable customer data from the disk. They could throw more exceptions. They could corrupt data in memory, making the bug impossible to diagnose.
So when an exception indicates an unknown state, you don't want to run any more code, so whatever you do, don't catch the exception. Let it fly past, and your program will terminate harmlessly, and Windows Error Reporting will be able to capture the state of the program as it was when the problem was originally detected. If you catch the exception, you will cause more code to execute, which will screw up the state of the program further.
Secondly, should you throw an exception knowing it won't be caught? I think that question misunderstands the nature of reusable methods. The whole idea of a method is that it has a "contract" that it follows: it accepts certain parameters and returns a certain value, plus also it throws certain exceptions under certain conditions. That's the contract - it's up to the caller what they do with it. For some callers, exception A might indicate a recoverable condition. For other callers, it might indicate a bug. And from what I said above, it should be clear that if an exception indicates a bug, it must not be caught.
And if you're wondering what this means for the Microsoft Enterprise Library's Exception Handling Block: yes, it's pretty broken. They tell you to catch (Exception x) and then decide whether to rethrow based on your policy; too late - the finally blocks have already executed by that point. Don't do that.
You probably wouldn't want an uncaught exception anywhere where the end-users can see it, but it is often acceptable to let clients of your API (other programmers) decide how to handle exceptions.
For example, suppose you are designing a Java class library. You expose a public method that takes in a String. In your application, a null input value would cause an error. Instead of handling the error yourself, it would be acceptable to check for a null value, then throw an IllegalArgumentException.
You must, of course, document that your method throws this exception in this circumstance. This behavior becomes part of your method's contract.
It depends on what you mean by 'being caught'. Something, somewhere eventually catches the exception whether it be the underlying OS or something else.
We have a workflow system that executes job plans comprised of individual jobs. Each job runs a unit of code. For some of the exceptions, we don't want to handle them in the code but throw it up the stack so that the external workflow system catches it (which happens completely outside of the thrower's process).
If you're writing the entire application, then your reasons are your own. I can think of a few situations where you might want to throw the exception and let the app die, most of them are not very good reasons though.
The best reason is usually when debugging. I frequently disable exceptions while debugging to allow me to know better where something is failing. You can also just turn on thrown exception breaks in the debugger if you're running it on a machine with the debugger.
Another possible reason is when continuing after an exception is thrown doesn't make sense or would result in possible irrecoverable data corruption or worse (think Robots with laser beams, but then you should be damn sure your applicaiton deals with these situations IMO, crashing the program is just the lazy way).
If you're writing API code, or Framework code that you won't use yourself, then you have no idea if someone will catch your exceptions.
Yup, it's my ONLY opportunity to slap the developer consuming the service/object to tell them "Ur dO1n it WrOnG!!!!".
That and getting rid of possibilities that you don't want to permit or are seemingly "impossible". Apps that catch all exceptions and continue are just a walled garden surrounded by chaos.
If I need a moderately large system that is somehow processing data in what I believe to be a consistent manner.
And
Somewhere along the line, I detect that the application's state has become inconsistent.
And
The system doesn't (yet) know how to fix the inconsistency and recover gracefully
Then, yes, I would throw an exception with as much detail as possible and cause the application to die as quickly as possible, to avoid doing any further harm to the data. If it can be recovered, it'd be important not to exacerbate the problem by trying feebly to cover up the mess.
Later along the line, once the chain of events that led to the inconsistency is better understood, I higher facility can catch that exception, repair the state, and continue with minimal interruption.
A library will often throw exceptions based on defensive programming checks, should a condition arise that shouldn't have been allowed to arise by the application code. Applications code will often be written such that most of those invalid conditions will never arise, and therefore the exceptions will never be thrown, so there's no point catching them.
Depending on language (I'm mostly thinking in terms of C++ rather than C#, and not that clear what the differences are) the effect of an uncaught exception actually being thrown is probably the same as what used to be done in the days before exceptions were invented. A common policy for defensive programming in C libraries, for example, was to terminate the program immediately with an error message.
The difference is that if the exception throw does turn out to be possible (hopefully this will be discovered through unit testing), it is often relatively easy to add an exception handler that can recover from the problem in a more constructive way. You don't have to rewrite the library, or add complex checks in application code to ensure the condition cannot arise before the exception-throwing call is made.
I have quite a few exception throws that are never caught. They are all for defensive purposes, and while being uncaught is bad for an exception that does happen, this only ever happens during development and testing, for error conditions I failed to consider in the application code so far. And when it happens, it is unusual for the fix to be awkward - no need for a large-scale refactoring, no need for the applications code to be massively complicated with error condition checks, just a catch clause with a relatively simple recovery or "I'm sorry, Dave, I'm afraid I can't do that." without failing out the whole app.
I've just come across a property setter that catches exceptions (all Exceptions; I know that's bad, but it's not relevant here), and only logs them. First of all, I think it should through them again as well; why wait for a crash and a log study when you can know something is wrong right away?
However, my main question is, do I validate against invalid date values, add a RuleViolation object to a ValidationRules object on my document, or throw an InvalidDate exception, or just let the CLR throw the exception for me (invalid dates are nothing but invalid dates, not checked for range etc.)
It depends on the specific task at hand. If you are writing a library class that will be used as a component in other programs and the contract of the method of the class says that it should only accept valid dates then throwing the Exception is fine.
If you are accepting user input and then waiting for an exception is a bad practice. In this case you should validate the date yourself.
Exceptions are for exceptional cases, and should not be part of your logic. It usually means that a contract was broken by the programmer.
Exceptions should be thrown whenever the method or class member is unable to complete whatever task it is designed to accomplish.
So for a property setter, if the setter is unable to set the property, then it should throw an exception.
As to whether you should catch it and rethrow it, the answer is yes, but only if you need to process the exception immediately in the setter, before passing it up the stack... but logging it is not a reason to do that. In general, you should implement cross-cutting logging of exceptions at a higher level, where the exception is NOT going to be re-thrown... if you are taking care of those cross-cutting concerns higher up the stack somewhere, then no, definitely do not catch and re-throw the same exception.
However, if you are writing a tool, or a framework library, where you want your component's clients to have a clearly defined set of expected exceptions, and you have defined your own custom exceptions that your component will throw to client code, and which client components will expect to see, then you may want to catch CLR generated exceptions and rethrow your own custom exceptions instead.. Always include the Actual underlying exception in your custom exceptions "InnerException" property before passing it up the stack, so that the data in it is available to whatever system end up consuming it.
It really depends on the logic of your application. Exceptions should only really be thrown for circumstances that are exceptional. For something like validation it depends on the tolerance for invalid data.
When you are building an interractive application and the user may enter anything, it is probably ok that the document gets into an invalid state and you should expose validation information via properties on the document class.
If you are processing pre-prepared documents from a database or log file then it probably isn't ok for the document to be invalid and continuing to operate after that might corrupt data in the system. When that happens you should throw.
I think it depends where the date values come from. If it comes from user input or some other source where it is perfectly well possible to enter 'invalid' dates, then validation would be the way to go. On the other hand, if there is no foreseeable reason why the data values might be invalid, then throwing an exception is appropriate.
Catching and rethrowing is the worst thing to do. Its expensive to TRY, if youre just going to rethrow what the point? You can catch unhandled exceptions with the global.asax for example if you need to log them.
In terms of validation, from a web perspective i always use regex validators for dates, these fire client and server side so i know when im inside an
if(Page.IsValid)
block that my txtDate.Text is a valid date, so i dont bother checking because its just wasteful.
We're reviewing one of the company's system's exception handling and found a couple of interesting things.
Most of the code blocks (if not all of them) are inside a try/catch block, and inside the catch block a new BaseApplicationException is being thrown - which seems to be coming from the Enterprise Libraries.
I'm in a bit of a trouble here as I don't see the benefits off doing this. (throwing another exception anytime one occurs)
One of the developers who's been using the system for a while said it's because that class's in charge of publishing the exception (sending emails and stuff like that) but he wasn't too sure about it.
After spending some time going through the code I'm quite confident to say, that's all it does is collecting information about the environment and than publishing it.
My question is:
- Is it reasonable to wrap all the code inside try { } catch { } blocks and than throw a new exception? And if it is, why? What's the benefit?
My personal opinion is that it would be much easier to use an HttpModule, sign up for the Error event of the Application event, and do what's necessary inside the module. If we'd go down this road, would we miss something? Any drawbacks?
Your opinion's much appreciated.
Never1 catch (Exception ex). Period2. There is no way you can handle all the different kinds of errors that you may catch.
Never3 catch an Exception-derived type if you can't handle it or provide additional information (to be used by subsequent exception handlers). Displaying an error message is not the same as handling the error.
A couple of reasons for this, from the top of my head:
Catching and rethrowing is expensive
You'll end up losing the stack trace
You'll have a low signal-to-noice ratio in your code
If you know how to handle a specific exception (and reset the application to pre-error state), catch it. (That's why it's called exception handling.)
To handle exceptions that are not caught, listen for the appropriate events. When doing WinForms, you'll need to listen for System.AppDomain.CurrentDomain.UnhandledException, and - if your doing Threading - System.Windows.Forms.Application.ThreadException. For web apps, there are similar mechanisms (System.Web.HttpApplication.Error).
As for wrapping framework exceptions in your application (non-)specific exceptions (i.e. throw new MyBaseException(ex);): Utterly pointless, and a bad smell.4
Edit
1 Never is a very harsh word, especially when it comes to engineering, as #Chris pointed out in the comments. I'll admit to being high on principles when I first wrote this answer.
2,3 See 1.
4 If you don't bring anything new to the table, I still stand by this. If you have caught Exception ex as part of a method that you know could fail in any number of ways, I believe that the current method should reflect that in it's signature. And as you know, exceptions is not part of the method signature.
If I am reading the question correctly, I would say that implementing a try / catch which intercept exceptions (you don't mention - is it catching all exceptions, or just a specific one?) and throws a different exception is generally a bad thing.
Disadvantages:
At the very least you will lose stack trace information - the stack you will see will only extend to the method in which the new exception is thrown - you potentially lose some good debug info here.
If you are catching Exception, you are running the risk of masking critical exceptions, like OutOfMemory or StackOverflow with a less critical exception, and thus leaving the process running, where perhaps it should have been torn down.
Possible Advantages:
In some very specific cases you could take an exception which doesn't have much debug value (like some exceptions coming back from a database) and wrap with an exception which adds more context, e.g id of the object you were dealing with.
However, in almost all cases this is a bad smell and should be used with caution.
Generally you should only catch an exception when there is something realistic that you can do in that location- ie recovering, rolling back, going to plan B etc. If there is nothing you can do about it, just allow it to pass up the chain. You should only catch and throw a new exception if there is specific and useful data available in that location which can augment the original exception and hence aid debugging.
I'm from the school of thought where try/ catch blocks should be used and exceptions not rethrown. If you have executing code which is likely to error then it should be handled, logged and something returned. Rethrowing the exception only serves the purpose to re-log later in the application life cycle.
Here's an interesting post on how to use a HttpModule to handle exceptions: http://blogs.msdn.com/rahulso/archive/2008/07/13/how-to-use-httpmodules-to-troubleshoot-your-asp-net-application.aspx and http://blogs.msdn.com/rahulso/archive/2008/07/18/asp-net-how-to-write-error-messages-into-a-text-file-using-a-simple-httpmodule.aspx
Check out ELMAH. It does what you're talking about. Very well.
When I create libraries I try to always provide a reduced number of exceptions for callers to handle. For example, think of a Repository component that connects to a sql database. There are TONS of exceptions, from sql client exceptions to invalid cast exceptions, that can theoretically be thrown. Many of these are clearly documented and can be accounted for at compile time. So, I catch as many of them as I can, place them in a single exception type, say a RepositoryException, and let that exception roll up the call stack.
The original exception is retained, so the original exception can be diagnosed. But my callers only need to worry about handling a single exception type rather than litter their code with tons of different catch blocks.
There are, of course, some issues with this. Most notably, if the caller can handle some of these exceptions, they have to root around in the RepositoryException and then switch on the type of the inner exception to handle it. Its less clean than having a single catch block for a single exception type. I don't think thats much of an issue, however.
Sounds like the exception that is thrown should not have been implemented as an exception.
Anyway, I would say that since this BaseApplicationException is a general all-purpose exception, it would be good to throw exceptions that are more context-specific. So when you are trying to retrieve an entity from a database, you might want an EntityNotFoundException. This way when you are debugging you do not have to search through inner exceptions and stack traces to find the real issue. If this BAseApplicationException is collecting information on the exception (like keeping track of the inner exception) then this should not be a problem.
I would use the HttpModule only when I could not get any closer to where the exceptions are actually happening in code. You do not really want an HttModule OnError event that is a giant switch statement depending on BaseApplicationexception's error information.
To conclude, it is worth it to throw different exceptions when you can give more specific exceptions that tell you the root of the problem right off the bat.
From my experience, catch the exception, add the error to the Server (?) object. This will allow .NET to do what ever it needs to do, then display your exception.