Are exception hierarchies really useful? - language-agnostic

It dawned on me that I've never seen a single exception hierarchy for which creating subclasses but catching the parent class was actually useful (except, of course, for the base Exception class, that has to be derived).
Are exception hierarchies really useful, xor should all exceptions be derived from language's base exception class?

Exception hierarchies are useful for grouping related exceptions together, when you need different granularity of catching in different places.
Putting all application exceptions in one place is the commonest use case. This allows you to catch MyAppException any time that you want to trap all errors coming from your application, but still catch more specific exceptions when appropriate. (In .NET, the ApplicationException class was meant for this, but it's been deprecated for various reasons.)
But you can also group exceptions together at module boundaries, or in any other way that makes sense. Use FooModuleException for exceptions coming from the Foo module, but catch and handle FooModuleMustFrobnicate specially internal to Foo. Or any equivalent situation.
I've used all of these patterns at different times.

TL;DR
Exception hierarchies are useless for catching exceptions (except for base differentiation btw. non-recoverable system errors (Java Error) and "normal" runtime exceptions. The notion that "you need different granularity of catching in different places" is IMHO fundamentally flawed. (Except, to reiterate, to differentiate between exceptions and assertions and other system wide unrecoverable stuff.)
Small exception hierarchies make sense in todays languages as a means of constructing different errors with as rich information as possible.
I am slowly coming to consider the whole concept of arbitrarily typed exceptions, as I see them implemented and supposed-to-be-used in C++, C# and Java as totally useless.
The problem is not so much the exception hierarchy per se, but that when I write code, and exception are exceptional, I don't care what type of exception was thrown for the purpose of catching it.
In all my coding in C++, Java and C#, I found -- for the exceptional exceptions, that were not misused for control flow -- not one case where I wanted to filter (i.e. catch or not catch) the exceptions by their "hierarchical" type. That is, there are rare cases where a function throws 3 different exceptions, and I want to specifically handle one of them, and handle the two others as general "fail" (like described below) but I never ever encountered this in a case where the exception hierarchy was useful in that I could meaningfully group the two cases by base classes.
If any operation (where I care) in my program fails with any exception, then this operations is considered failed, and:
I get what info I can from the caught object
continue with contextualized error handling (re-throw, display error, log, re-try, recover, etc.)
I think Java is the only of the three languages that at least has the right approach with their hierarchy, namely:
Throwable not used in user code
Error the stuff you never want to catch - just core dump
Exception - for all the stuff you basically always want to catch (except for when an Interface is botched and uses an Exception when it really shouldn't)
//
The hierarchy of C++'s <stdexcept> has the right basic approach in differentiating between logic_error - basically assertions - and runtime_error - stuff that just unexpectedly failed. (The subclasses of theses are largely irrelevant when catching.)
Except of course that too much stuff derives directly from std::exception so you can't make use of the differentiation provided by runtime and logic error. (And of course any code is free to throw whatever they want, so chances are good that there's a bunch of logic_error derived classes that really should be runtime_errors and vice-versa.
To quote another answer:
Exception hierarchies are useful for grouping related exceptions
together, when you need different granularity of catching in different
places.
but in my experience I never want "catching in different places", because it just doesn't make sense.
I either want catching, in which case I catch everything (modulo stuff like the Error class exceptions from Java) or I don't want to catch, in which case the hierarchy is not needed, because there is no catch.
Take opening and reading from a file:
If there is (would be) any exception type I specifically care about, because I can do something about it ("recover"), then this should not be reported as an exception at all, because it is normal control flow. (If the error is such-and-such, I can do such-and-such basically locally.)
If on the other hand, I can't do anything about an error but record the file operation as failed, then having any catch granularity is utterly useless.

I've never created a single exception hierarchy for whole application, because an exception in general can bring different semantic and, therefore, needs to handled differently.
Some exceptions inform about system faults, another exceptions inform about bugs, and some other - about some exceptional condition, that could be gracefully recovered on higher level.
For this "business-logic" exceptions exception hierarchy can help you not to violate open-closed principle during overriding some methods in descendants.
Consider following example:
public abstract class Base
{
/// Perform some business-logic operation
/// and throw BaseFooException in certain circumstances
public abstract void Foo();
}
public class Derived1 : Base
{
/// Perform some business-logic operation
/// and throw DerivedFooException in certain circumstances.
/// But caller could catch only BaseFooException
public abstract void Foo() {}
}
class BaseFooException : Exception {}
class DerivedFooException : BaseFooException {}
Exception hierarchy may be helpful in custom framework or in specific libraries, but in general case (in business applications) I don't think that creating one deep and wide exception hierarchy is a good idea.

Related

Do exceptions break encapsulation?

In the first place, a class or library is created when you do not want to worry about the details of an implementation, but then you need to know the inner workings of the class to properly handle the exceptions it might throw.
Doesn't this break the principle of encapsulation and information hiding ? Or I am totally wrong on this ?
Sure I can have a generic try/catch block to intercept all exceptions, but that is definitely a bad practice.
So how can I come up with good exception handling strategy without knowing the details of each exceptions that might be thrown ?
A well-designed class or library will document what exceptions it throws as part of the interface, perhaps even going so far as to define its own hierarchy of exception classes. For instance, a foo subclass class might throw a "foo persistence exception" if the disk is full, and another subclass would throw one if the network is down. As the caller, you would catch a foo persistence exception because your concern is that data was not persisted. You shouldn't be expected to write code specifically for disk full, network down, disk not present, disk write error, subspace transceiver interference, &c.
It may be the case that you can't do much about many of them.
A class library does not have to throw the same exceptions that its code throws. For expected exceptions that cannot be handled internally, it should probably map to alternate exception types where the "raw" exception would not be readily understood by API consumers. An API consumer should be able to regard expected exceptions as outputs of the API, as one would any other product of usage of the API. Unexpected exceptions, on the other hand, are a whole other ball of wax for both the API developer and consumer...
It's not like that; it's for the end users who are using the end products OR the class "need not to know the inner implementation" but you will know it for sure and hence can hendle the error mechanism accordingly.
BTW, that's the reason any API comes with a good documentation ... so that other developers know at least a bit of it's inner working.
Hopefully this clears the idea.
In the first place, a class or library is created when you do not want
to worry about the details of an implementation, but then you need to
know the inner workings of the class to properly handle the exceptions
it might throw.
Doesn't this break the principle of encapsulation and information
hiding ? Or I am totally wrong on this ?
An exception should thrown when the calee can't fulfill its promises due to some runtime error and can't recover from that state. What exceptions could be thrown must be specified in the interface/documentation. I don't see how this breaks encapsulation. On the other hand, using return codes can't enforce the caller to treat an exceptional error, even by explicitly ignoring it.
Sure I can have a generic try/catch block to intercept all exceptions,
but that is definitely a bad practice.
It is if the designer of the interface you're using didn't clearly specify what exceptions could be thrown and by whom/what_function
So how can I come up with good exception handling strategy without
knowing the details of each exceptions that might be thrown ?
The "details" are in fact the exceptions specifications and that's all you need to know. Again, it should be part of documentation/interface.
Anyway, exceptions should happen rarely, probably thats why someone named them exceptions. If it would happen too often then someone wouldn't name them exceptions anymore but "usuality" or something and the normal, exception-free "code" will become an exception :)
If you're working too much with try/catch bollocks then something is wrong with that code.

Why is it a "bad idea" to throw your own exceptions?

Why is it a "bad idea" to throw your own exceptions?
found here
In general, it is perfectly fine to throw your own exceptions. Perhaps what you meant to ask was "When is it not necessarily a good idea to throw my own exception?"
One case is when you should be throwing a standard exception. For example, if your method takes a file name and is supposed to return a file, you should probably throw your platform's standard FileNotFoundException rather than throw PeanutPowersFileNotFoundException. If you really want to throw your own exception, you should probably have it extend the standard FileNotFoundException.
Update: Bloch explains this in Item 60 of Effective Java
It's not. You should create and throw custom exceptions whenever you have an exceptional situation.
It isn't provided they are derived from whatever the standard base exception type is (std::exception in c++, or Exception in python, etc...)
If they _aren't_derived from the normal base type, then other people may not catch them when they are expecting to catch all exceptions - which would be a bad thing.
It's not wrong to create your own exception type. However, before going through creating your own, you should check whether your framework already provides an exception that fits.
From the .Net design guidelines:
Consider throwing existing exceptions
residing in the System namespaces
instead of creating custom exception
types.
Do create and throw custom exceptions
if you have an error condition that
can be programmatically handled in a
different way than any other existing
exceptions. Otherwise, throw one of
the existing exceptions.
Do not create and throw new exceptions
just to have your team's exception.
I believe you might be asking why is it a bad idea to re-throw exceptions.
By "rethrow", I mean catching an exception and than generating a new one and throwing it. This can be problematic, as you could end up consuming the original stack trace and loosing all context of the error.
You should not invent your own type of Exception, unless you have something extra you want to add to the Exception type.
If you want to tell the user of your API that they have provided an invalid argument, you should throw an ArgumentException, but if your library fails because of some library specific reason, that you can't convey in a regular exception, you should roll your own and let it contain the info the developer needs.
To continue Peter's response another case when throwing an exception is not a good idea is if you use throwing exceptions to control the business logic of your program.
As long as the exception you are throwing is derived from a proper object, and conveys just that - exceptional situation, throwing an exception is totally acceptable.
Using throwing exceptions to control business logic in addition to being a bad design pattern has also performance implications - throwing and catching exceptions is rather expensive as compared to branching based on the results returned from the method
There's nothing wrong with creating your own exceptions, which can be tailored to convey exactly the information which is appropriate for your situation. A ConfigFileNotFoundException conveys more information than a FileNotFoundException (which file didn't we find?).
But, by all means, make sure that you catch and handle each and every custom exception inside of your code. When the exception flies to some place outside your module (call it package, call it namespace), those folks out there will not even know that it exists, much less what to do with it. Except for a catch (Throwable t) {/* whut? */}.
To me it seems that the question is to catch inexperienced candidates trying to fake experience. There's nothing wrong about throwing your own exceptions in my opinion, and as you can see to everyone else that answered here.
It's not a bad idea at all. If an exceptional situation arises, an exception should be thrown to handle it, especially if you're designing code that others may use, may receive bad input, etc.
It is a bad idea to use exceptions where they're not absolutely necessary, such as situations that are recoverable by normal checks in code or as part of normal execution, since they do have a lot of overhead associated with them. I imagine that's where you may have gotten the idea that they're a bad idea in general. But for what they're meant to do (flagging an exceptional situation that your code isn't equipped to handle), they're absolutely the best tool.
And if you do create custom exceptions for code others might use, do document what they are and what they mean. That way later users of your code will know that they're possible and what they mean if they arise, and can handle them appropriately.

Exceptions and Abstractions

When should you throw a custom exception?
e.g. I have some code that connects to a server. The code that connects to the server throws an IOException when it fails to connect. In the context of the method it's called, this is fine. It's also fine in the network code.
But as this represents not having a connection (and therefore not working) the exception goes all the way up to the ui. At this stage, an IOException is very ambigous. Something like NoConnectionException would be better.
So, my question is:
At what stage should you catch an exception to instead throw another (custom) exception that better fits the abstraction?
I would expect exceptions to talk in terms of what I've asked the originating method to do. e.g.
read -> ReadException
connect -> ConnectException
buildPortfolio -> FailedToBuildPortfolioException
etc. This abstracts away what's going on under the covers (i.e. are you connecting via sockets etc.). As a general rule, when I create an interface for a component, I often create a corresponding exception or set of exceptions. My interface will be called Component, and my exceptions are usually ComponentException (e.g. RateSource and RateSourceException). It's consistent and easy to export to different projects as a complete component set.
The downside is that you create quite a lot of exceptions, and you may have to perform quite a lot of translations. The upside is that (as you've identified) you get little to no abstraction leakage.
At some point during the hierarchy of method calls (and thus exceptions) you may decide that no recovery can take place (or it's at an inappropriate place) and translate to unchecked exceptions to be handled later.
I know this is tagged as "language-agnostic", but I don't think it really is. Coming from a C++ perspective, I expect very few basic operations to throw an exception - the C++ Standard Library only uses exceptions in a very few places. So my own code is often the first place where exceptions can be generated. In that code, I like a very flat hierarchy - I don't want to be messing with hundreds of catch() clauses later in the code, and have never understood Java and C#'s apparent obsession with creating Baroque heirarchies of class and namespace.
So, for my C++ code - one type of exception, containing a meaningful error message, per library. And one for the final executable.
I think there are two questions hidden here:
a) When should one hide an exception behind a different exception.
b) When should one use a custom exception for this.
a) I'd say: when ever an exception travels across the border of two layers in the application, it should get hidden behind an exception that is more apropriate for the new layer.
Example: because you are doing some remote stuff, you get a ConnectionWhatEverException.
But the caller shouldn't be aware of Connection problems. Since he just wants to get some service performed, so he gets a ServiceOutOfOrderException. The reason for this is: Inside the layer, doing remoting, you might to do something usefull with a ConnectionException (retry, write into a backout queue ..). Once you left that layer, nobody knows how to handle a ConnectionException. But they should be able to decide, what do do, when the Service does not work.
b) When there is no matching existing Exception. There are a couple of useful Exception in Java for example. I use IllegalState and IllegalArgument quite often. A strong argument for a new exception class is, if you have some useful context to provide. For example the name of the service that failed could be an argument of a ServiceFailedException. Just don't create a class for every method call, or anything to that effect. 100 Exception classes aren't a problem, as long as they have different behavior (i.e. at least different fields). If they differ only by name and reside on the same abstraction level, make them one Exception, and put the different names in the message or a single field of that exception class.
c) At least in java there is the discussion about checked exceptions. I wrap those directly in an unchecked one, because I hate the checked kind. But that is more an opinion then advice.
Is there any case where you would get NoConnectionException which isn't caused by an IO issue? Conversely, is knowing whether the cause is IO based or not going to help the client recover sensibly?
When should you throw a custom exception?
I. When you can provide more (diagnostic) information.
Note: this additional information may not be available at the place where the original exception (IOException) was thrown. Progressive layers of abstractions may have more information to add like what were you trying to do which led to this exception?
II. When you must not expose implementation details: i.e. you want the (illusion of?) abstraction to continue.
This may be important when the underlying implementation mechanism can change. Wrapping the underlying exception in a custom exception is a good way of insulating your clients from implementation details (by lifting the level of abstraction)
III. Both I and II
NOTE: Furthermore your clients should be able to tune into the exact level of information they are interested in or rather they should be able to tune out anything they are not interested in. So it's a good idea to derive your custom exceptions from IOException.

preconditions and exceptions

Suppose you have a method with some pre and post-conditions.
Is it ok to create an exception class for each pre-condition that is not accomplished?
For example:
Not accomplishing pre1 means throwing a notPre1Exception instance.
Why wouldn't you want to define PreconditionFailedException(string precondition)? Throwing a different exception type for each failed precondition is overkill.
Yes and no.
Yes - Violating a precondition is certainly an appropriate time to throw an exception. Throwing a more specific exception will make catching that specific exception simpler.
No - Declaring a new exception class for every precondition in your program/api seems way overkill. This could result in hundreds or thousands of exceptions eventually. This seems a waste both mentally and computationally.
I would recommend throwing exceptions for precondition violations. I would not, however, recommend defining a new exception for each precondition. Instead, I would recommend creating broader classes of exceptions that cover a specific type of precondition violation, rather than a specific precondition violation. (I would also recommend using existing exceptions where they fit well.)
A failed precondition should throw an AssertException, or something similar. Before invoking a method, it's precondition must hold. If the caller doesn't do this check, it's a bug in the program, or an incorrect use of the method (API).
Only if not accomplishing the pre-conditions would be a rare exceptional occurrence.
Sounds like a useful use of exceptions to me. It certainly allows more fine-grained logging and debugging than just a general 'precondition failed' although you could also have a single 'preconditions failed' exception and put what preconditions have failed into the exception message.
I think it's ok to create a different exception for all your exceptions as long as you plan on using and handling them.
I have found that the better the error/exception handling the easier it is to debug software in the later stages.
For example: If you have a generic excpeiton to handle all bad input then you must look at everything that was passed into the method if there is an error. If you have an excpetion of all the types of bad conditions you will know exaclty where to look.
It looks possible to me, but if you want to continue this way of dealing with preconditions, you'll end up with N exception classes per class method. Looks like an explosive growth of 'non functional' classes.
I always liked code where the 'core' functionality didn't handle violation of preconditions (apart from asserting them - a great help!). This code can then be wrapped in a 'precondition-checker', which does throw exceptions or notifies non-satisfaction otherwise.
As a very very general way to determine if you should ever create a class or not (and an exception is a class), you should determine if there is some code that makes this class unique from all other classes (in this case exceptions).
If not, I'd just set the string in the exception and call it a day. If you are executing code in your exception (perhaps a generic recovery mechanism that can handle multiple situations by calling exception.resolve() or something), then it might be useful.
I realize that exceptions don't always follow this rule, but I think that's more or less because exceptions provided by the language can't have any business logic in them (because they don't know the business--libraries always tend to be full of exceptions to the OO rules)
I think Ben is on target here. What's the point in throwing different exceptions if you're not going to catch them? If you really want to throw a different one I would at least have a common "PreconditionFailedException" base class that they all derive from, and try to organize them into some sort of heirachy so you can catch groups of them. Personlly, I'd not have different ones and just have a common exception you throw with the details of the failure in each one.
No, you should not create a specific exception for each precondition because it will go against the principles of the Design-by-Contract.
The corollaries of implementing pre-conditions is that they should be part of the documentation and that you should provide the necessary methods for the caller to check that all the preconditions are valid. (i.e. if a method execution is relying on the status of an object, the method to check the status should be available to the caller).
So, the caller should be able to check if all prerequisites are met before calling your method.
Implementing specific exceptions for each violated pre-condition would/could encourage the caller to use the try/catch pattern around the method call, what is in contradiction with the philosophy of the Design-by-Contract.
I would say it's okay as long as you make them unchecked exceptions (subclass of RuntimeException in Java). However, in Java it is better to just use assertions.
If you do this, make sure they all inherit from another common custom exception.

When to throw an exception?

I have exceptions created for every condition that my application does not expect. UserNameNotValidException, PasswordNotCorrectException etc.
However I was told I should not create exceptions for those conditions. In my UML those ARE exceptions to the main flow, so why should it not be an exception?
Any guidance or best practices for creating exceptions?
My personal guideline is: an exception is thrown when a fundamental assumption of the current code block is found to be false.
Example 1: say I have a function which is supposed to examine an arbitrary class and return true if that class inherits from List<>. This function asks the question, "Is this object a descendant of List?" This function should never throw an exception, because there are no gray areas in its operation - every single class either does or does not inherit from List<>, so the answer is always "yes" or "no".
Example 2: say I have another function which examines a List<> and returns true if its length is more than 50, and false if the length is less. This function asks the question, "Does this list have more than 50 items?" But this question makes an assumption - it assumes that the object it is given is a list. If I hand it a NULL, then that assumption is false. In that case, if the function returns either true or false, then it is breaking its own rules. The function cannot return anything and claim that it answered the question correctly. So it doesn't return - it throws an exception.
This is comparable to the "loaded question" logical fallacy. Every function asks a question. If the input it is given makes that question a fallacy, then throw an exception. This line is harder to draw with functions that return void, but the bottom line is: if the function's assumptions about its inputs are violated, it should throw an exception instead of returning normally.
The other side of this equation is: if you find your functions throwing exceptions frequently, then you probably need to refine their assumptions.
Because they're things that will happen normally. Exceptions are not control flow mechanisms. Users often get passwords wrong, it's not an exceptional case. Exceptions should be a truly rare thing, UserHasDiedAtKeyboard type situations.
My little guidelines are heavily influenced by the great book "Code complete":
Use exceptions to notify about things that should not be ignored.
Don't use exceptions if the error can be handled locally
Make sure the exceptions are at the same level of abstraction as the rest of your routine.
Exceptions should be reserved for what's truly exceptional.
It is NOT an exception if the username is not valid or the password is not correct. Those are things you should expect in the normal flow of operation. Exceptions are things that are not part of the normal program operation and are rather rare.
I do not like using exceptions because you can not tell if a method throws an exception just by looking at the call. Thats why exceptions should only be used if you can't handle the situation in a decent manner (think "out of memory" or "computer is on fire").
One rule of thumb is to use exceptions in the case of something you couldn't normally predict. Examples are database connectivity, missing file on disk, etc. For scenarios that you can predict, ie users attempting to log in with a bad password you should be using functions that return booleans and know how to handle the situation gracefully. You don't want to abruptly end execution by throwing an exception just because someone mistyped their password.
Others propose that exceptions should not be used because the bad login is to be expected in a normal flow if the user mistypes. I disagree and I don't get the reasoning. Compare it with opening a file.. if the file doesn't exist or is not available for some reason then an exception will be thrown by the framework. Using the logic above this was a mistake by Microsoft. They should have returned an error code. Same for parsing, webrequests, etc., etc..
I don't consider a bad login part of a normal flow, it's exceptional. Normally the user types the correct password, and the file does exist. The exceptional cases are exceptional and it's perfectly fine to use exceptions for those. Complicating your code by propagating return values through n levels up the stack is a waste of energy and will result in messy code. Do the simplest thing that could possibly work. Don't prematurely optimize by using error codes, exceptional stuff by definition rarely happens, and exceptions don't cost anything unless you throw them.
I think you should only throw an exception when there's nothing you can do to get out of your current state. For example if you are allocating memory and there isn't any to allocate. In the cases you mention you can clearly recover from those states and can return an error code back to your caller accordingly.
You will see plenty of advice, including in answers to this question, that you should throw exceptions only in "exceptional" circumstances. That seems superficially reasonable, but is flawed advice, because it replaces one question ("when should I throw an exception") with another subjective question ("what is exceptional"). Instead, follow the advice of Herb Sutter (for C++, available in the Dr Dobbs article When and How to Use Exceptions, and also in his book with Andrei Alexandrescu, C++ Coding Standards): throw an exception if, and only if
a precondition is not met (which typically makes one of the following
impossible) or
the alternative would fail to meet a post-condition or
the alternative would fail to maintain an invariant.
Why is this better? Doesn't it replace the question with several questions about preconditions, postconditions and invariants? This is better for several connected reasons.
Preconditions, postconditions and invariants are design characteristics of our program (its internal API), whereas the decision to throw is an implementation detail. It forces us to bear in mind that we must consider the design and its implementation separately, and our job while implementing a method is to produce something that satisfies the design constraints.
It forces us to think in terms of preconditions, postconditions and invariants, which are the only assumptions that callers of our method should make, and are expressed precisely, enabling loose coupling between the components of our program.
That loose coupling then allows us to refactor the implementation, if necessary.
The post-conditions and invariants are testable; it results in code that can be easily unit tested, because the post-conditions are predicates our unit-test code can check (assert).
Thinking in terms of post-conditions naturally produces a design that has success as a post-condition, which is the natural style for using exceptions. The normal ("happy") execution path of your program is laid out linearly, with all the error handling code moved to the catch clauses.
Exceptions are a somewhat costly effect, if for example you have a user that provides an invalid password, it is typically a better idea to pass back a failure flag, or some other indicator that it is invalid.
This is due to the way that exceptions are handled, true bad input, and unique critical stop items should be exceptions, but not failed login info.
I would say there are no hard and fast rules on when to use exceptions. However there are good reasons for using or not using them:
Reasons to use exceptions:
The code flow for the common case is clearer
Can return complex error information as an object (although this can also be achieved using error "out" parameter passed by reference)
Languages generally provide some facility for managing tidy cleanup in the event of the exception (try/finally in Java, using in C#, RAII in C++)
In the event no exception is thrown, execution can sometimes be faster than checking return codes
In Java, checked exceptions must be declared or caught (although this can be a reason against)
Reasons not to use exceptions:
Sometimes it's overkill if the error handling is simple
If exceptions are not documented or declared, they may be uncaught by calling code, which may be worse than if the the calling code just ignored a return code (application exit vs silent failure - which is worse may depend on the scenario)
In C++, code that uses exceptions must be exception safe (even if you don't throw or catch them, but call a throwing function indirectly)
In C++, it is hard to tell when a function might throw, therefore you must be paranoid about exception safety if you use them
Throwing and catching exceptions is generally significantly more expensive compared to checking a return flag
In general, I would be more inclined to use exceptions in Java than in C++ or C#, because I am of the opinion that an exception, declared or not, is fundamentally part of the formal interface of a function, since changing your exception guarantee may break calling code. The biggest advantage of using them in Java IMO, is that you know that your caller MUST handle the exception, and this improves the chance of correct behaviour.
Because of this, in any language, I would always derive all exceptions in a layer of code or API from a common class, so that calling code can always guarantee to catch all exceptions. Also I would consider it bad to throw exception classes that are implementation-specific, when writing an API or library (i.e. wrap exceptions from lower layers so that the exception that your caller receives is understandable in the context of your interface).
Note that Java makes the distinction between general and Runtime exceptions in that the latter need not be declared. I would only use Runtime exception classes when you know that the error is a result of a bug in the program.
If it's code running inside a loop that will likely cause an exception over and over again, then throwing exceptions is not a good thing, because they are pretty slow for large N. But there is nothing wrong with throwing custom exceptions if the performance is not an issue. Just make sure that you have a base exception that they all inherite, called BaseException or something like that. BaseException inherits System.Exception, but all of your exceptions inherit BaseException. You can even have a tree of Exception types to group similar types, but this may or may not be overkill.
So, the short answer is that if it doesn't cause a significant performance penalty (which it should not unless you are throwing a lot of exceptions), then go ahead.
Exception classes are like "normal" classes. You create a new class when it "is" a different type of object, with different fields and different operations.
As a rule of thumb, you should try balance between the number of exceptions and the granularity of the exceptions. If your method throws more than 4-5 different exceptions, you can probably merge some of them into more "general" exceptions, (e.g. in your case "AuthenticationFailedException"), and using the exception message to detail what went wrong. Unless your code handles each of them differently, you needn't creates many exception classes. And if it does, may you should just return an enum with the error that occured. It's a bit cleaner this way.
the rule of thumb for throwing exceptions is pretty simple. you do so when your code has entered into an UNRECOVERABLE INVALID state. if data is compromised or you cannot wind back the processing that occurred up to the point then you must terminate it. indeed what else can you do? your processing logic will eventually fail elsewhere. if you can recover somehow then do that and do not throw exception.
in your particular case if you were forced to do something silly like accept money withdrawal and only then check user/pasword you should terminate the process by throwing an exception to notify that something bad has happened and prevent further damage.
I agree with japollock way up there--throw an acception when you are uncertain about the outcome of an operation. Calls to APIs, accessing filesystems, database calls, etc. Anytime you are moving past the "boundaries" of your programming languages.
I'd like to add, feel free to throw a standard exception. Unless you are going to do something "different" (ignore, email, log, show that twitter whale picture thingy, etc), then don't bother with custom exceptions.
I'd say that generally every fundamentalism leads to hell.
You certainly wouldn't want to end up with exception driven flow, but avoiding exceptions altogether is also a bad idea. You have to find a balance between both approaches. What I would not do is to create an exception type for every exceptional situation. That is not productive.
What I generally prefer is to create two basic types of exceptions which are used throughout the system: LogicalException and TechnicalException. These can be further distinguished by subtypes if needed, but it is not generally not necessary.
The technical exception denotes the really unexpected exception like database server being down, the connection to the web service threw the IOException and so on.
On the other hand the logical exceptions are used to propagate the less severe erroneous situation to the upper layers (generally some validation result).
Please note that even the logical exception is not intended to be used on regular basis to control the program flow, but rather to highlight the situation when the flow should really end. When used in Java, both exception types are RuntimeException subclasses and error handling is highly aspect oriented.
So in the login example it might be wise to create something like AuthenticationException and distinguish the concrete situations by enum values like UsernameNotExisting, PasswordMismatch etc. Then you won't end up in having a huge exception hierarchy and can keep the catch blocks on maintainable level. You can also easily employ some generic exception handling mechanism since you have the exceptions categorized and know pretty well what to propagate up to the user and how.
Our typical usage is to throw the LogicalException during the Web Service call when the user's input was invalid. The Exception gets marshalled to the SOAPFault detail and then gets unmarshalled to the exception again on the client which is resulting in showing the validation error on one certain web page input field since the exception has proper mapping to that field.
This is certainly not the only situation: you don't need to hit web service to throw up the exception. You are free to do so in any exceptional situation (like in the case you need to fail-fast) - it is all at your discretion.
In general you want to throw an exception for anything that can happen in your application that is "Exceptional"
In your example, both of those exceptions look like you are calling them via a password / username validation. In that case it can be argued that it isn't really exceptional that someone would mistype a username / password.
They are "exceptions" to the main flow of your UML but are more "branches" in the processing.
If you attempted to access your passwd file or database and couldn't, that would be an exceptional case and would warrant throwing an exception.
Firstly, if the users of your API aren't interested in specific, fine-grained failures, then having specific exceptions for them isn't of any value.
Since it's often not possible to know what may be useful to your users, a better approach is to have the specific exceptions, but ensure they inherit from a common class (e.g., std::exception or its derivatives in C++). That allows your client to catch specific exceptions if they choose, or the more general exception if they don't care.
Exceptions are intended for events that are abnormal behaviors, errors, failures, and such. Functional behavior, user error, etc., should be handled by program logic instead. Since a bad account or password is an expected part of the logic flow in a login routine, it should be able to handle those situations without exceptions.
The simple answer is, whenever an operation is impossible (because of either application OR because it would violate business logic). If a method is invoked and it impossible to do what the method was written to do, throw an Exception. A good example is that constructors always throw ArgumentExceptions if an instance cannot be created using the supplied parameters. Another example is InvalidOperationException, which is thrown when an operation cannot be performed because of the state of another member or members of the class.
In your case, if a method like Login(username, password) is invoked, if the username is not valid, it is indeed correct to throw a UserNameNotValidException, or PasswordNotCorrectException if password is incorrect. The user cannot be logged in using the supplied parameter(s) (i.e. it's impossible because it would violate authentication), so throw an Exception. Although I might have your two Exceptions inherit from ArgumentException.
Having said that, if you wish NOT to throw an Exception because a login failure may be very common, one strategy is to instead create a method that returns types that represent different failures. Here's an example:
{ // class
...
public LoginResult Login(string user, string password)
{
if (IsInvalidUser(user))
{
return new UserInvalidLoginResult(user);
}
else if (IsInvalidPassword(user, password))
{
return new PasswordInvalidLoginResult(user, password);
}
else
{
return new SuccessfulLoginResult();
}
}
...
}
public abstract class LoginResult
{
public readonly string Message;
protected LoginResult(string message)
{
this.Message = message;
}
}
public class SuccessfulLoginResult : LoginResult
{
public SucccessfulLogin(string user)
: base(string.Format("Login for user '{0}' was successful.", user))
{ }
}
public class UserInvalidLoginResult : LoginResult
{
public UserInvalidLoginResult(string user)
: base(string.Format("The username '{0}' is invalid.", user))
{ }
}
public class PasswordInvalidLoginResult : LoginResult
{
public PasswordInvalidLoginResult(string password, string user)
: base(string.Format("The password '{0}' for username '{0}' is invalid.", password, user))
{ }
}
Most developers are taught to avoid Exceptions because of the overhead caused by throwing them. It's great to be resource-conscious, but usually not at the expense of your application design. That is probably the reason you were told not to throw your two Exceptions. Whether to use Exceptions or not usually boils down to how frequently the Exception will occur. If it's a fairly common or an fairly expectable result, this is when most developers will avoid Exceptions and instead create another method to indicate failure, because of the supposed consumption of resources.
Here's an example of avoiding using Exceptions in a scenario like just described, using the Try() pattern:
public class ValidatedLogin
{
public readonly string User;
public readonly string Password;
public ValidatedLogin(string user, string password)
{
if (IsInvalidUser(user))
{
throw new UserInvalidException(user);
}
else if (IsInvalidPassword(user, password))
{
throw new PasswordInvalidException(password);
}
this.User = user;
this.Password = password;
}
public static bool TryCreate(string user, string password, out ValidatedLogin validatedLogin)
{
if (IsInvalidUser(user) ||
IsInvalidPassword(user, password))
{
return false;
}
validatedLogin = new ValidatedLogin(user, password);
return true;
}
}
for me Exception should be thrown when a required technical or business rule fails.
for instance if a car entity is associated with array of 4 tires ... if one tire or more are null ... an exception should be Fired "NotEnoughTiresException" , cuz it can be caught at different level of the system and have a significant meaning through logging.
besides if we just try to flow control the null and prevent the instanciation of the car .
we might never never find the source of the problem , cuz the tire isn't supposed to be null in the first place .
the main reason for avoiding throwing an exception is that there is a lot of overhead involved with throwing an exception.
One thing the article below states is that an exception is for an exceptional conditions and errors.
A wrong user name is not necessarily a program error but a user error...
Here is a decent starting point for exceptions within .NET:
http://msdn.microsoft.com/en-us/library/ms229030(VS.80).aspx
Throwing exceptions causes the stack to unwind, which has some performance impacts (admitted, modern managed environments have improved on that). Still repeatedly throwing and catching exceptions in a nested situation would be a bad idea.
Probably more important than that, exceptions are meant for exceptional conditions. They should not be used for ordinary control flow, because this will hurt your code's readability.
I have three type of conditions that I catch.
Bad or missing input should not be an exception. Use both client side js and server side regex to detect, set attributes and forward back to the same page with messages.
The AppException. This is usually an exception that you detect and throw with in your code. In other words these are ones you expect (the file does not exist). Log it, set the message, and forward back to the general error page. This page usually has a bit of info about what happened.
The unexpected Exception. These are the ones you don't know about. Log it with details and forward them to a general error page.
Hope this helps
Security is conflated with your example: You shouldn't tell an attacker that a username exists, but the password is wrong. That's extra information you don't need to share. Just say "the username or password is incorrect."
I have philosophical problems with the use of exceptions. Basically, you are expecting a specific scenario to occur, but rather than handling it explicitly you are pushing the problem off to be handled "elsewhere." And where that "elsewhere" is can be anyone's guess.
To my mind, the fundamental question should be whether one would expect that the caller would want to continue normal program flow if a condition occurs. If you don't know, either have separate doSomething and trySomething methods, where the former returns an error and the latter does not, or have a routine that accepts a parameter to indicate whether an exception should be thrown if it fails). Consider a class to send commands to a remote system and report responses. Certain commands (e.g. restart) will cause the remote system to send a response but then be non-responsive for a certain length of time. It is thus useful to be able to send a "ping" command and find out whether the remote system responds in a reasonable length of time without having to throw an exception if it doesn't (the caller would probably expect that the first few "ping" attempts would fail, but one would eventually work). On the other hand, if one has a sequence of commands like:
exchange_command("open tempfile");
exchange_command("write tempfile data {whatever}");
exchange_command("write tempfile data {whatever}");
exchange_command("write tempfile data {whatever}");
exchange_command("write tempfile data {whatever}");
exchange_command("close tempfile");
exchange_command("copy tempfile to realfile");
one would want failure of any operation to abort the whole sequence. While one could check each operation to ensure it succeeded, it's more helpful to have the exchange_command() routine throw an exception if a command fails.
Actually, in the above scenario it may be helpful to have a parameter to select a number of failure-handling modes: never throw exceptions, throw exceptions for communication errors only, or throw exceptions in any cases where a command does not return a "success" indication.
You may use a little bit generic exceptions for that conditions. For e.g. ArgumentException is meant to be used when anything goes wrong with the parameters to a method (with the exception of ArgumentNullException). Generally you would not need exceptions like LessThanZeroException, NotPrimeNumberException etc. Think of the user of your method. The number of the conditions that she will want to handle specifically is equal to the number of the type of the exceptions that your method needs to throw. This way, you can determine how detailed exceptions you will have.
By the way, always try to provide some ways for users of your libraries to avoid exceptions. TryParse is a good example, it exists so that you don't have to use int.Parse and catch an exception. In your case, you may want to provide some methods to check if user name is valid or password is correct so your users (or you) will not have to do lots of exception handling. This will hopefully result in more readble code and better performance.
Ultimately the decision comes down to whether it is more helpful to deal with application-level errors like this using exception handling, or via your own home-rolled mechanism like returning status codes. I don't think there's a hard-and-fast rule about which is better, but I would consider:
Who's calling your code? Is this a public API of some sort or an internal library?
What language are you using? If it's Java, for example, then throwing a (checked) exception puts an explicit burden on your caller to handle this error condition in some way, as opposed to a return status which could be ignored. That could be good or bad.
How are other error conditions in the same application handled? Callers won't want to deal with a module that handles errors in an idiosyncratic way unlike anything else in the system.
How many things can go wrong with the routine in question, and how would they be handled differently? Consider the difference between a series of catch blocks that handle different errors and a switch on an error code.
Do you have structured information about the error you need to return? Throwing an exception gives you a better place to put this information than just returning a status.
Some useful things to think about when deciding whether an exception is appropriate:
what level of code you want to have run after the exception candidate occurs - that is, how many layers of the call stack should unwind. You generally want to handle an exception as close as possible to where it occurs. For username/password validation, you would normally handle failures in the same block of code, rather than letting an exception bubble up. So an exception is probably not appropriate. (OTOH, after three failed login attempts, control flow may shift elsewhere, and an exception may be appropriate here.)
Is this event something you would want to see in an error log? Not every exception is written to an error log, but it's useful to ask whether this entry in an error log would be useful - i.e., you would try to do something about it, or would be the garbage you ignore.
"PasswordNotCorrectException" isn't a good example for using exceptions. Users getting their passwords wrong is to be expected, so it's hardly an exception IMHO. You probably even recover from it, showing a nice error message, so it's just a validity check.
Unhandled exceptions will stop the execution eventually - which is good. If you're returning false, null or error codes, you will have to deal with the program's state all by yourself. If you forget to check conditions somewhere, your program may keep running with wrong data, and you may have a hard time figuring out what happened and where.
Of course, you could cause the same problem with empty catch statements, but at least spotting those is easier and doesn't require you to understand the logic.
So as a rule of thumb:
Use them wherever you don't want or simply can't recover from an error.
I would say that exceptions should be thrown if an unexpected behaviour is occuring that wasnt meant to be.
Like trying to update or delete a non existing entity. And it should be catched where the Exception can be handled and has meaning. For working in an alternative way to continue, add logging or returning a specific result on Api level.
If you expect something to be the case, you should build code to check and ensure it.