What are checked exceptions in Java/C#? - c#

I am a C# developer doing occasional coding in Java. Can someone explain in simple terms what are checked exceptions in Java and why is it needed? Haven't come across this term in C#.

Checked exceptions are exceptions that the compiler require you handle in some way.
In Java, checked exceptions are Throwables that are not RuntimeException, Error, or one of their subclasses.
The Java designers felt they were needed to ensure programs handled exceptions that were reasonably likely. A classic example is IOException. Any time a program does I/O, there is a possibility of failure. The disk could be full, the file might not exist, there might be a permissions problem, etc.
Thus, Java is designed such that a program must syntactically handle the exception in some way. This could be with a catch block, or by rethrowing the exception in some way.
C# does not have checked exceptions. They decided to leave this issue up to the application developers (interview). Checked exceptions are controversial because they can make code verbose, while developers sometimes handle them trivially with empty catch blocks. Further, it can be arbitrary which standard library methods throw checked exceptions. For instance, why doesn't File.delete (a new Java 7 API does this differently) throw IOException?
Another concern Hejlsberg noted in that interview is versionability. Adding a checked exception to a throw clause forces all code using that method to be modified and recompiled.

In Java, a checked exception (as Matthew Flaschen correctly points out) is an exception that the compiler requires you to handle. These are exceptions that are declared on function definitions (e.g. function bob() throws ImNotBobException { ... } to say that calling that function may throw that exception - e.g. NumberFormatException when parsing an integer, or IOException when writing to a file.
However, some exceptions can be thrown from unknown or unexpected places that are simply impractical to handle on every level, so the compiler does not require you to handle these. These are unchecked exceptions. They can be thrown from various places that do not declare to throw them (often by attempting to call a method on an object when that object has not been initialised yet, i.e. is null - this will result in a NullPointerException.)
Hope this helps.

Checked exceptions are exceptions that require any "consuming" class to have to code that explicitly checks (and hopefully handles) the exception.
For example, if the Apple class has an Eat() method which includes the checked exception of WormFound then any code that calls that method will need to explicitly have a catch for that exception.
As a side note, it is feature of Java and not of C#.
(At the point when C# was created, the pros of checked exceptions weren't so obvious in the eyes of the C# team so they weren't included.)

Related

How to explicitly document that a method does not throw exceptions

Using XML comments in C#, I can document that a method may throw an exception:
<exception cref="FooException">Thrown if foo is invalid.</exception>
However, if a method has no exception tag in its XML documentation, this may mean one of two things:
The author thoroughly tested the method, has made sure it will never throw an exception, and wants to document this fact by not adding an exception tag.
The author didn't care about documenting exceptions, so this method may throw anything.
In my experience, the second is usually the case. The question is, then:
How do I explicitly document that a method will never throw an exception?
The best I've come up with so far is to simply mention it in the method's summary, like "This method does not throw exceptions". But I was wondering if there is a more formal way to express this, like throw() in C++ (even though that may be a bad example).
Adding it in the summary is good for documentation and communication with other developers.
You said you want to have a more formal way, tough.
From what I know of C# (very little), Exception has two main child classes, ApplicationException and SystemException. You generally can't guarantee that a system exception won't be thrown. We may however guarantee that no ApplicationException is ever thrown.
1. With contracts
With code contracts, you may use EnsuresOnThrow post-conditions:
Contract.EnsuresOnThrow<ApplicationException>( false );
2. Without contracts
Wrap the body of your code in a global try/catch, and assert False in the catch block.
In both cases, a static analyzer should understand that the assertion or post-condition can never be true when an exception occurs: thus, the application fullfills its contracts if and only if no exception is ever thrown from your function.

How to know if some method can throw an exception

I'm new in a developement for Windows 8 and C#, but I have certain experience with Java Programming.
So, when I try to make some Json parser (for example) in java, I can't do it without use a try - catch block, and this way I can handle the exception, but when I try to do the same in c# (Windows 8) and I don't use the try - catch block it works too, like this:
if (json != null)
{
JObject jObject = JObject.Parse(json);
JArray jArrayUsers = (JArray)jObject["users"];
foreach (JObject obj in jArrayUsers)
{
ListViewMainViewModel user = new ListViewMainViewModel(
(String)obj["email"],
(String)obj["token"],
(String)obj["institution"],
(String)obj["uuidInstitution"]);
usersList.Add(user);
}
return usersList;
}
}
As I know the right way is to catch JsonReaderException, but Visual Studio never warned me on that. I would like to know if there's a easy way to know if some method throw an exception, like is on java using eclipse (it's mandatory implement try-catch block or code wont compile)
You will have to consult the documentation for that. C# lacks a throws keyword.
The term for what you are looking for is checked exceptions, and more info can be found in the C# FAQ.
In C# you are responsible for handling exceptions - which IMHO is the better way of going about it than the Java implementation. In effect, an exception should be, well exceptional, that is: It isn't something you should just always expect to happen.
Consider this weirding (yet, common) anti-pattern:
try {
} catch (Exception ex) { /* Handler goes here */ }
What exactly does that mean? Are you really going to handle every single exception that passes through here? Even stuff like OutOfMemoryExceptions? That's nuts. The only thing this sort of pattern will lead to is suppressing legitimate exceptions that really ought to bring down the application - this is fairly similar to the Java approach.
Think of an Exception as being a flag to the programmer that says 'hey, the environment just entered an impossible state'. For example, if I try to divide by zero and the system throws a DivideByZeroException, then rightly the system should alert you to this, because this is a failure - one the system can't just 'figure it's way out of' - and if you simply suppress the issue, how is that really helping? In the end this is counter-productive, in that all you're doing is masking over what is really an impossible application state. If you do this a lot in your application, then it eventually just devolves into a sludge of toxic wrong-ness. Yuck!
Exceptions also take up a lot of screen real estate. Sometimes I wish they would make the try/catch/finally blocks a little more streamlined, but then I remember that doing so would encourage people to use them more, so I repent of that position pretty quick.
Exceptions are useful programmer-to-programmer notifications saying that something you're doing doesn't make sense. Obviously we should never pass raw exceptions to the user because they won't know what to do with them. At the same time, you don't want to try to handle every single exception on the face of the earth, because 'handling' in this sense typically transforms into 'suppression', which is way worse than just letting the application fail (gracefully).
C#, as has been mentioned, does not have checked exceptions, and thank goodness.
The idea of checked exceptions sounds great on its face, but talk to anyone who is forced to use them by language or runtime, and they'll say there are three big problems with checked exceptions:
They impose their will upon the consuming coder. Checked exceptions, by their definition, are expected to be handled before they are thrown out of the runtime. The runtime is in effect telling the coder "you should know what to do when I throw this, so do so". First off, think about it; you are told to expect something that happens in exceptional cases by its very definition. Second, you're expected to somehow handle it. Well, that's all well and good when you actually have the ability to address the problem the exception indicates. Unfortunately, we don't always have that ability, nor do we always want to do everything we should. If I'm writing a simple form applet that performs a data transformation, and I just want my application to die a fiery death if there's any problem, I can't just not catch anything; I have to go up all possible call stacks of every method that could throw something and add what it could throw to the throws clause (or be extremely lazy and put a "throws Exception" clause on every method of my codebase). Similarly, if my app is constructed such that I can't throw out a particular exception, perhaps because I'm implementing an interface beyond my control that doesn't specify it as a potential throwable, then my only options are to swallow it entirely and return a possibly invalid result to my callers, or to wrap the exception in an unchecked throwable type like a RuntimeException and throw it out that way (ignoring the entire checked exception mechanism, which is not recommended of course).
They violate SOLID, especially the Open-Closed Principle. Make a change that adds a checked exception to your code, and if you can't handle said exception, all usages of your method must either handle it or mark themselves as throwing the exception. Usages which rethrow must be handled by their own callers or they have to be marked as throwing the same exception. By making a change as surgical as calling an alternate method in a particular line of code, you now have to trace up all possible call stacks and make other changes to code that was working just fine, just to tell them your code could conceivably throw an exception.
They create leaky abstractions by definition. A caller consuming a method with a "throws" clause must, in effect, know these implementation details about its dependency. It must then, if it is unwilling or unable to handle these errors, inform its own consumers about these errors. The problem is compounded when the method is part of an interface implementation; in order for the object to throw it, the interface must specify it as a throwable, even if not all of the implementations throw that exception.
Java mitigates this by having a multilevel hierarchy of Exception classes; all I/O-related exceptions are (supposed to be) IOExceptions, for instance, and an interface with methods that have IO-related purposes can specify that an IOException can be thrown, relieving it of the responsibility to specify each specific child IOException. This causes almost as many problems as it solves, however; there are dozens of IOExceptions, which can have very different causes and resolutions. So, you must interrogate each IOException that you catch at runtime to obtain its true type (and you get little or no help identifying the specific ones that could be thrown) in order to determine whether it's something you can handle automatically, and how.
EDIT: One more big problem:
They assume try-catch is the only way to handle a possible exception situation. Let's say you're in C# in an alternate universe where C# has Java-style checked exceptions. You want your method to open and read a file given a filename passed into it by the caller. Like a good little coder, you first validate that the file exists in a guard clause, using File.Exists (which will never throw an exception; in order to return true, the path must be valid, the file specified at the path must exist, and the executing user account must have at least read access to the folder and file). If File.Exists returns false, your method simply returns no data, and your callers know what to do (say this method opens a file containing optional config data, and if it doesn't exist, is blank or is corrupted, your program generates and uses a default configuration).
If the file exists, you then call File.Open. Well, File.Open can throw nine different types of exceptions. But none of them are likely to occur, because you already verified using File.Exists that the file can be opened read-only by the user running the program. The checked exception mechanism, however, wouldn't care; the method you're using specifies it can throw these exceptions, and therefore you must either handle them or specify that your own method can throw them, even though you may take every precaution to prevent it. The go-to answer would be to swallow them and return null (or to forget the guard clause and just catch and handle File.Open's exceptions), but that's the pattern you were trying to avoid with the guard clause in the first place.
None of this even considers the potential for evil. A developer might, for instance, catch and encapsulate an unchecked exception as a checked one (for instance, catching a NullPointerException and throwing an IOException), and now you have to catch (or specify that your method throws) an exception that isn't even a good representation of what's wrong.
As far as what to use instead in C#, the best practice is to use XML documentation comments to inform the immediate caller using your method that an exception could potentially be thrown from it. XML-doc is the .NET equivalent to JavaDoc comments, and is used in much the same way, but the syntax is different (three forward slashes followed by the comments surrounded with a system of XML tags). The tag for an exception is easy enough to specify. To efficiently document your codebase, I recommend GhostDoc. It will only generate exception comments for exceptions explicitly thrown from inside the method being documented, however, and you'll have to fill in some blanks.
I'm not a java developer, but from the answers here it seems as though the Java implementation is a burden to clients of those methods. However, C# missed an opportunity (Java-like or otherwise) to communicate to the caller the type of exceptional outcomes that could happen, as authored by the developer of the method, allowing me the caller to handle it appropriately.
Since this construct isn't built into the language, I would suggest to library developers that you adopt a wrapper class and use it as the return type for any methods that could go awry. Using said class as the return type in lieu of exceptions, clients can reason about what to expect when calling the method, as it is clearly defined in the method signature. Also, using the wrapper would allow a method to tell a client why something went awry in a way does not break the flow like exceptions do.
More on this subject here: http://enterprisecraftsmanship.com/2015/03/20/functional-c-handling-failures-input-errors/

Is it normal to use many business exceptions if needed?

Is it a good practice to define and throw custom exceptions even if the application needs lots of them?
EntityNotFoundException
EntityAlreadyExistsException
EntityNotUniqueException
EntityNotAddedException
EntityNotUpdatedException
EntityNotDeletedException
QuizOverException
QuizExpiredException
TableAlreadyBookedException
EndDateMustBeGreaterThanStartDateException
I tried to name these sample exception names to describe their purpose as good as I could. I hope they could form an idea of what I am trying to ask.
Don't limit your imagination with only these exceptions but all that could arise during you application's life. Consider both CRUD and business exceptions.
I know that throwing and catching exceptions is an expensive process in terms of performance but don't they provide a more elegant way to develop you app?
Isn't it better to throw a EntityNotFoundException instead of writing an if statement to check whether the entity is null?
Isn't it better to throw a EntityAlreadyExistsException instead of writing an additional if statement which will call a method to check whether the entity with the given Id already exists?
Isn't it better to throw a EntityNotAddedException instead of checking the return value of type bool specifying whether the transaction was successful or not? What if we want to return an object?
I feel that the answer will be like "you should not use EntityNotFoundException but instead check if null, but you should use EntityAlreadyExistsException", "there is no holy grail".
I am wondering what is the elegant way of doing this?
Keeping in mind that exceptions are supposed to represent exceptional circumstances all of your questions can only really be answered with - it depends.
The context of when & where you intend on throwing a particular exception will naturally decide whether it makes sense. For example, if you attempt to retrieve an entity that should exist but doesn't, then throwing an EntityNotFoundException would be considered appropriate because we now have an exceptional circumstance. On the other hand, if you are checking whether the entity already exists before creating a new one then you could argue that because we know there is a chance the entity may or may not exist then it's not really an exceptional circumstance.
Like I said, it really depends on the context of the situation and the nature of your application whether you should throw an exception or not, however, the one thing you don't want to end up doing is controlling the program flow with exceptions.
To help make the distinction between when it's suitable to use an exception vs business logic, simply ask yourself "is this particular situation valid?" or in other words "is it OK for the application to find itself in this state?". If the answer is yes, use logic to control the flow of the application and deal with the situation, otherwise you want to throw an Exception to effectively interrupt the program flow and inform the user that something isn't quite right.
When creating exceptions ask about their added value.
Will someone care about specific types of exception to be caught?
Will exceptions have different fields to help exception handling?
More abstract exception with custom message can save you time writing exceptions with no value.
Using exceptions to control program flow is considered bad idea. Here are some reasons:
Exceptions have been created for concept of error handling
Performance as you said
you can forget to handle some exceptions
If you use checked exceptions you may need to write handlers for exceptions you do not care about or don't know how to handle.
Exceptions increase uncertainty in programs (exceptions thrown while exception handling, finally statements,...)
There are other ways to solve conditional statements, take a look at scala programming language and its use of "monads".
One major limitation with the exception-handling paradigm in C++, which was inherited by Java and subsequently .NET, is that if a call to Foo throws a BozException, that can have two very different meanings:
Some condition was detected during the execution of Foo which implied that it should throw a BozException.
Foo called some method which it was not expecting to throw a BozException, but the method threw one anyway and Foo didn't catch it, the exception was thrown out of Foo.
Even though the Framework guidelines discourage the use of custom exceptions when an existing exception would seem to "fit", the lack of any standard means for code that catches a Framework-defined exception to know whether it actually represents an expected circumstance is a pretty big disadvantage to using a Framework exception (like InvalidOperationException) to report business-logic circumstances a caller might want to handle (e.g. trying to add to a Dictionary to records with the same ID). If you can tolerate the boilerplate associated with defining exceptions, I'd suggest that it's better to err on the side of too many rather than too few (though you may wish to use inheritance for exceptions that will likely be handled the same way).
As with almost everything in software development, given a general rule or best practise the skill is knowing when and how to apply it.
Should I program to an interface? YES! Should I make every single class I write implement a corresponding interface and only ever program to that abstraction? I could do but writing a very simple application would take me an age and my productivity would grind to a halt.
Single Responsibility - is it a good thing? YES! Does every class I write have exactly one and only one responsibility. No - partly because of my own failings as a programmer, but also because I'd end up with a plethora of single-method classes and an unmanageably disconnected code base.
Now let us turn to error handling:
Firstly, by looking at your comment to James' answer, let us clarify that using error codes and exception handling represent two distinct models of handling errors in your application and as a general rule they should not be mixed.
Let us assume you are using exception handling and make the following argument:
Why do we throw exceptions?
We throw an exception because something bad has happened. If we are expecting a scenario to occur some point, then it is within the flow of our application, and is therefore not exceptional - so throwing an Exception would not be appropriate!
With this argument, it makes little sense to throw anything other than the top level Exception class, as any other exception implies that we have foreseen this scenario and have been able to attach extra metadata to the exception.
Why handle exception?
Having thrown an exception, we expect someone somewhere to deal with it, hopefully with the intention of restoring the application to a consistent state. However, if the exception is truly exceptional - we can have no way of knowing what state has been corrupted so exception handling is futile.
Isn't this taking things a bit too far?
Well - this is exactly how error handling works in a service orientated architecture. A robust service should not reveal any incriminating details of what has happened when an exception occurs (it's a security breach and introduces coupling between the service and the client) - all the client needs to know is something bad happened.
However, I'm guessing that we are working within an Object Orientated environment, where we are prepared to accept a slightly higher degree of coupling between an implementation and it's consumers. And it is this that is the important point - by introducing an exception hierarchy which exposes detailed information about the exception you increase the coupling in your application (the consumers need to have detailed knowledge about all the exceptions you could throw).
In software we strive for a loosely coupled code base, making it easy to maintain and extend. I have no doubt there is a happy medium between the SOA approach to exceptions and the one you describe in your question - finding that sweet spot is the skill of the developer.

How to descern fatal from non fatal .NET Exceptions

I'm writing a general discrete event system simulation library in C#. I'm going to write another library on top of that which will implement a specific kind of discrete event sim. Here is an integral version of the code.
static class Engine
{
[ThreadStatic] internal static uint time;
//...
public static void Run(OnException onException = OnException.PauseAndRethrow,
IList<Type> exceptionsToPass = null)
{
//...
while (!stop)
{
Event e = currentTimeEventQueue.PopEvent();
if (e == null) break;
try {
e.Activate();
}
catch (EngineException ex)
{
// An engine method that shouldn't have been called
// was called, and Activate didn't handle that
// handle this situation...
}
catch (/* fatal exception type*/ ex)
{
throw;
}
catch (Exception ex)
{
// code to decides whether to dismiss exception
// pause, stop, reset based on parameters to this method
}
}
}
}
The question is: Should I specifically catch Exception types that are known to be unrecoverable (that I shouldn't try to handle in any way). What are those Exceptions (I can think of OutOfMemoryException and StackOverflowException). Is there a list of fatal Exceptions? As I remember some of them are uncatchable. So I am interested in a list of fatal Exceptions that can be caught. I just want to rethrow them, and not do anything. On the other hand I want to handle any other type of Exception. Or maybe I need another angle on this.
EDIT: OK, I've made a huge oversight when writing the question. Activate() is abstract. I am writing a general purpose discrete event system simulation library. The engine is working with totally unknown subclasses of Event. So it is calling an absolutely unknown method Activate(), that could throw any kind of exception. I could just ignore this issue, but I want to give control of the process to the caller. As you can see from the parameters to the Run() method, the caller decides what the engine will do if an exception comes from a call to Activate() (it can instruct the engine to ignore and continue, or pause and rethrow, or ...). That is why I am trying to separate fatal from all other Exceptions. If the caller has instructed the engine to ignore any exception that comes from Activate() it would be unwise to catch and ignore fatal exceptions. (there be dragons :) )
Should I specifically catch Exception types that are known to be unrecoverable
No. You shouldn't. If they are unrecoverable you shouldn't try to recover from them.
The rule regarding exceptions is - catch and handle exceptions that you know how to recover from. Let any other bubble up - if this means an application crash, this is probably for the best.
The following is a code smell and shouldn't be coded:
catch (/* fatal exception type*/ ex)
{
throw;
}
No throwable is really "uncatchable"; anything that can be thrown in .NET derives from Exception and so can be caught. However, many things shouldn't be caught. Hence your question; how to tell the difference?
The general rule I follow is "Catch the exceptions that you expect and know how to deal with". This requires you to first know what your code could throw. The MSDN docs are usually pretty good at stating what various framework methods will throw in what situations; your own codebase is likely less well-documented unless you're developing an intermediate library to be consumed by other coders (or your management/leads are anal about proper documentation).
Once you know what the code can throw, determine what, if anything, you should catch. Exception trapping, aka "Pokemon handling" (Gotta catch 'em all) is generally a bad thing because there are legitimate reasons to let your application die a fiery death and make the user restart it. Examples include StackOverflowExceptions, OutOfMemoryExceptions, and various Win32Exceptions detailing some internal failure to provide your program with the requested resources. You usually cannot recover from these in any meaningful way.
Most errors, however, are not that serious. Exceptions are thrown when a file isn't found, or when a network connection is refused or unexpectedly closed, or when you attempt to do something with a type without checking for null (and what happens when the check for null fails? Often you can't continue and must throw an exception of your own). These are things that you should be expecting, catching, and at the very least communicating to the end user in some understandable way.
In many cases, try/throw/catch is a useful tool for expected but not everyday situations; if you receive a timeout exception while waiting for results when usually there's no problem getting results, then don't even tell the user there was a problem; just try again. If you can (should?) plug in some default value when a calculation can't be evaluated (divide by zero, math that could produce non-real results but the code can't handle them, etc etc), then do so.
There is, however, one scenario I can think of where you simply must catch and rethrow, and that's in situations involving database transactions. If you're performing a large "unit of work" with a database transaction handling several persistence operations along the way, then if anything goes wrong, you should roll back the DB transaction. In that case, the operation should be surrounded in a try-catch(Exception) block that catches the exception, rolls back the transaction, and rethrows. Any exception that you can proceed through normally should be handled with a nested try-catch or the condition should be checked for prior to the operation that could fail in that way.
Your question is a reasonable one to ask, but alas there is often no really good answer. A major weakness with the exception paradigm in C++, which unfortunately follows through into other languages and frameworks which borrow from it, is that it encapsulates way too much in the type of an exception object. In C++, this is understandable, since Bjarne Stroustrup wanted to avoid having any non-primitive types be "hard-coded" into the language; given that constraint, the C++ design may have been the best possible. Nonetheless, such a design imposes some serious limitations.
The biggest problem is that code which is considering catching and processing an exception, and then either swallowing or rethrowing it, may be interested in a number of things:
What happened that prevented code from behaving as expected
What actions should be taken in response to the condition
Once various actions have been taken, should the condition be considered "resolved"
Should one adjust one's assumptions about any aspects of the system state beyond what is implied by the method's failing (e.g. if file "foo/bar" couldn't be read, the nature of the failure may impact a decision whether to try reading "foo/boz").
In Java and .net, the expectation is that the exception type should be used to indicate #1 above, and there's no standard means for exceptions to answer #2 and #3, even though they are in many cases far more important than "what happened". If one tries to load a document and something goes wrong, 99% of the time the system will be in the same state as it was before the load attempt, so the exception, regardless of its type, will basically mean "file isn't readable and wan't loaded". Further, in that remaining 1% of the time where something "bad" happens beyond the failure to load the file, it's entirely possible that the exception type will be the same as one that's thrown in the 99%.
Absent some new exception-handling features, one's best bet is probably, to the extent possible, have exceptions that indicate state corruption invalidate the corrupted parts of system state such that all future operations on those parts will likewise throw exceptions. Such behavior will mean that exceptions that code can't handle will end up bringing down the system (since the code will keep trying to use parts of the state that have become corrupted), while allowing code to recover from things it should recover from (e.g. if an exception occurs because of corruption in an object which was being built, and if the exception causes code to abandon the object under construction, such abandonment would suffice to "handle" the exception, and so execution can and should continue).

Defining exceptions that can be thrown from a toolkit API

Is there a best-practice or industry standard for throwing exceptions from a toolkit API?
Should the user facing methods catch and wrap up Exception in some sort of CustomException so that users only have to worry about CustomExceptions coming out of the API?
Or is the convention to just let those bubble up?
We're concerned with being able to document all possible exceptions our API methods might throw. (For example, if our API method calls Stream.Write() which throws 4 or 5 exceptions, we'd have to document all of those in addition to other exceptions that other called methods might throw.)
We were thinking of doing something like this:
public void customerFacingApiMethod(){
try {
//api functionality goes here
} catch (Exception e) {
throw new CustomException(e);
}
}
In my opinion having the API throwing only one exception type is a bad idea. One of the good things with different exceptions is that you can choose to catch different types of exceptions and handle them differently. Wrapping up exceptions into a single exception type would remove that facility.
Use the exception types provided by the framework where appropriate, and create your own custom exception types for specific situations where appropriate. And above all, make sure to document for each method which exceptions they may throw.
When throwing exceptions, make sure that the user-facing exceptions are all relevant to what the user actually did wrong with regards to your toolkit. That might mean catching or merging different filesystem exceptions into a single exception but you shouldn't ever just catch Exception and throw a new one - that's not actually telling the toolkit user what they did wrong.
You should follow the same concepts as the .NET Framework. Your users already use the framework, so they know how it works and expect certain behavior.
Throw an ArgumentException-derived exception if an argument from the client is invalid (use ArgumentNullException, ArgumentOutOfRangeException, etc. as appropriate).
Throw an IOException-derived exception for IO errors.
Etc...
In your documentation, clearly state the preconditions for your public API and state the exceptions that will be thrown when they fail (like MSDN does).
I don't like it. If you wrap all exceptions into a CustomException it will be difficult to catch specific exceptions without searching inside the object for the InnerExcpetion (possibly multiple levels deep if your API also uses other APIs that do the same thing). If there's an OutOfMemoryException, I'd like to know that without having to go searching for it.
Don't use the same exception for all.
You need the different exception types to be able to separate one case from another. For anything that you'd let it flow up until a generic exception handler block catches it would seem k, but you are preventing any other code recovery - extra actions that operate on specific cases.
You can wrap a set of exceptions, if those fit into a specific scenario that can be handled by the calling code. Don't forget that some framework exceptions already communicate the situation well.
What Fredrik Mork says is very true. I also like to add to that that you can easily document the exceptions that are thrown with xml comments (and GhostDoc).
So an API user can lookup in the documentation to see what exceptions can be thrown. However, there is a downside.
If you have a deep callstack inside your API and especially if the cyclomatic complexity becomes high (i.e. num of possible branches) you cannot recover all possible exceptions that can be thrown (perhaps by the runtime?)
So i would recommend to only throw if something if recovery is not possible and only throw in the upper layer of your API, i.e. no deeper than 2 deep. And catch all exceptions that are thrown deeper in your callstack and return them as InnerException or something like that.
There are two types of exceptions to consider (ignoring StackOverflowException, etc., which you can't do anything about anyway):
Those that are caused by external issues (like file IO), which have to be handled.
Those that can always be avoided with properly validated input.
It usually makes sense for the IO-type exceptions to be passed up the call stack unmodified, since there isn't anything you can really do about it anyway. Exceptions to this would be anticipated errors for which you might do retries, or asking the user what to do, if your API operates at the GUI level (which would be rather unusual).
Just be sure to document which exceptions of this type your API methods can throw.
Of the second type (exceptions that can always be prevented), these exceptions may be generated by your API on bad input, but should never be passed up the call-stack from the lower levels. Input to anything you call should be validated so that these errors do not occur, and if, for some reason, they can occur, then these exceptions should be wrapped up. Otherwise, the code that uses your API will have to deal with exceptions at the wrong level of abstraction.
And once again, be sure to document what sort of input will not generate exceptions, and what kinds of exceptions to expect if these rules are broken.
In all cases, throw exceptions that make sense to the user of your API, not the person programming the API itself.
The problem with catching System.Exception in the general case is that by doing so, you're effectively saying "I don't have any idea of why this failed, and that's okay, because I know I can continue anyway!"
That's rarely, if ever, true.
Wrapping up all exceptions in a single custom exception type means that your consumers will just catch that type - which is then the moral equivalent of catching System.Exception. While you may satisfy some policy/FXCop rule by doing that, you're really still just catching System.Exception.
For your exception policy, I'd start with asking this: "If I didn't know what this API actually talked to, what kind of exception would I expect to get back?" And remember that a method is a request to an object to do something, and an exception is the object's way of letting you know that it couldn't, and why.
If you create a single exception type for use throughout your API, its meaning will be vague to client applications that encounter that exception type. Instead, consider creating an exception class hierarchy for your API.
To do so, first define an abstract base exception type:
CustomException
...and then derive more specific exception types from it. For example:
CustomFooException
CustomBarException
CustomFizException
CustomFuzException
The abstract base type CustomException will never be directly thrown from your API. However, a client of your API can catch the base exception type CustomException if it doesn't care about which specific derived exception was thrown from your API.
For more on the idea of developing an exception class hierarchy, see this answer and other answers to this question: Why create custom exceptions in .NET?
Also see this answer which introduces the idea of making the base class of your exception hierarchy abstract.

Categories