Axon4 - Standard exception handling mechanism - exception

What is standard exception handling mechanism for Axon4 ?
Addiotnaally - how do you ensure that if exception occours during one of the event in Saga (in between state), previous states gets rolled back ?
Any example would help.

This is quite a broad question you're asking here Prashant, with a couple of answers to it. Additionally, your asking two questions, one being what the exception handling approach is and two how to deal with exceptions in Sagas.
So, as you're talking about Sagas and events, I am going to take the stance that you want to know the exception handling process around events. Let me first answer your first question here.
As you might have read in the Reference Guide, Axon uses what's called an EventProcessor as the technical mechanism to get events to your 'event handling components' and Saga instances.
The EventProcessors allow two different levels of exception handling:
1. When an exception occurs in the #EventHandler/#SagaEventHandler annotated function, this can be caught in the ListenerInvocationErrorHandler.
2. When an exception occurs in the EventProcessor, this can be caught in the ErrorHandler.
Both of these can be set in Axon 4 by dealing with the EventProcessingConfigurer and calling their respective register functions, which allow you to set a global default or adjust these per Event Processor.
The defaults are respectively the LoggingErrorHandler and the PropagatingErrorHandler.
The second question your asking is about how to rollback state in a Saga when an exception occurs. The suggestion I'd like to give you here is that upon receiving an event, you change the state first and only after that will you perform other operations.
Other operations like calling a third party service or publishing a command.
These operations might as you've noticed fail with an exception. This should however not rollback the state of the Saga at all.
The event already happened. The fact that the operation after that failed does not change the fact of that event having occurred.
Thus what I do suggest is that you perform a compensating action if such an exception occurs.

Related

How to differentiate between exceptions i can show the user, and ones i can't?

i have some business logic that traps some logically invalid situations, e.g. trying to reverse a transaction that was already reversed. In this case the correct action is to inform the user:
Transaction already reversed
or
Cannot reverse a reversing transaction
or
You do not have permission to reverse transactions
or
This transaction is on a session that has already been closed
or
This transaction is too old to be reversed
The question is, how do i communicate these exceptional cases back to the calling code, so they can show the user?
Do i create a separate exception for each case:
catch (ETransactionAlreadyReversedException)
MessageBox.Show('Transaction already reversed')
catch (EReversingAReversingTransactionException)
MessageBox.Show('Cannot reverse a reversing transaction')
catch (ENoPermissionToReverseTranasctionException)
MessageBox.Show('You do not have permission to reverse transactions')
catch (ECannotReverseTransactionOnAlredyClosedSessionException)
MessageBox.Show('This transaction is on a session that has already been closed')
catch (ECannotReverseTooOldTransactionException)
MessageBox.Show('This transaction is too old to be reversed')
Downside for this is that when there's a new logical case to show the user:
Tranasctions created by NSL cannot be reversed
i don't simply show the user a message, and instead it leaks out as an unhandled excpetion, when really it should be handled with another MessageBox.
The alternative is to create a single exception class:
`EReverseTransactionException`
With the understanding that any exception of this type is a logical check, that should be handled with a message box:
catch (EReverseTransactionException)
But it's still understood that any other exceptions, ones that involve, for example, an memory ECC parity error, continue unhandled.
In other words, i don't convert all errors that can be thrown by the ReverseTransaction() method into EReverseTransactionException, only ones that are logically invalid cause of the user.
I find that there are various broad categories of exception:
TransientException - what you just tried didn't work, but if your try again it might. Used for cases such as Database not currently available.
InvalidRequestException - you just asked for something that can't be done (Your examples fit here)
SystemException - The system is sick, we've forgotten everything you just said, your session is dead, you need to start all over again.
I would have these three main types of exception and catch each of them, there being obvious specific actions in each case. All my exceptions derive from these three types.
To me the rule of thumb is whether it is useful for the user to see the exact error message. This varies wildly between different types of applications. A desktop app used by millions of "average users" is a very different case from an enterprise web app used by a coupe hundred trained professionals.
For the former, it might be better to display a generic "system error, please restart" type message instead of technical details which the user doesn't understand and is usually not bothered to forward to the support department anyway (unless it can be done with the press of a button).
Our project is of the latter case, and the users typically forward problems to support. So we try to improve the error messages to contain information relevant to the support team. Since ours is a legacy app, we are much less worried about memory parity errors than plain null pointer exceptions and logical errors in the code though.
As for the number of distinct exception types, I am a fan of simplicity so I try to get by with the minimum necessary number of exception types, one for each distinct error category. What constitutes a separate category is also defined by how and when that bug can occur, and how and when it is handled. Since your cases above all are associated with the same use case, I would use a single exception type with specific detail messages.
I recommend the single exception with a cause identifier. The cause itself could be an exception which is wrapped in your user exception, although I would consider this mostly for debugging purposes, or as a means to derive additional details.
Your main exception includes an identifier, which identifies succinctly what the user has done wrong. It can be used as the basis for retrieving localized messages to show the user, for linking to user documentation, help, troubleshooting, and other assistance.
The message ID is also useful as an error code which can be used when reporting problems and for documenting solutions in support documentation for your support team.
I use a superclass for all user-level exceptions that allow the use of an ID to identify the situation or cause. All the IDs are documented, and each has at least one test cases to provoke the exception.
Are you deriving all of your exceptions from the base Exception (or EException or whatever the equivalent is in your language?)
I handle this by deriving all business logic errors from a ClientException (the user provided invalid input) or BusinessRuleException (input was valid but would unwittingly violate some important business or domain rule).
Any exception that derives from either of these roots can be caught and displayed to the user. Other exceptions go to the global exception handler, unless the code knows specifically how to handle them.
(Actually, that's not entirely accurate. What really happens is that the global exception handler itself recognizes these exceptions and handles them differently. But the principle is the same.)
You should create separate exceptions when you need (or expect to need) different types of behavior to handle the different exceptions. If you just want different messages displayed, but the basic behavior will be the same for all of them, then you probably just want to derive one exception class from std::runtime_error:
class transaction_error : public std::runtime_error {
public:
transaction_error(std::string const &caption) : std::runtime_error(caption) {}
};
which you'd throw something like:
throw transaction_error("Transaction already reversed");
...and catch something like:
try {
execute_transaction(transaction_data);
}
catch(transaction_error const &e) {
MessageBox(NULL, e->what(), "Transaction Error", MB_OK);
}

Why should I not wrap every block in "try"-"catch"?

I have always been of the belief that if a method can throw an exception then it is reckless not to protect this call with a meaningful try block.
I just posted 'You should ALWAYS wrap calls that can throw in try, catch blocks.' to this question and was told that it was 'remarkably bad advice' - I'd like to understand why.
A method should only catch an exception when it can handle it in some sensible way.
Otherwise, pass it on up, in the hope that a method higher up the call stack can make sense of it.
As others have noted, it is good practice to have an unhandled exception handler (with logging) at the highest level of the call stack to ensure that any fatal errors are logged.
As Mitch and others stated, you shouldn't catch an exception that you do not plan on handling in some way. You should consider how the application is going to systematically handle exceptions when you are designing it. This usually leads to having layers of error handling based on the abstractions - for example, you handle all SQL-related errors in your data access code so that the part of the application that is interacting with domain objects is not exposed to the fact that there is a DB under the hood somewhere.
There are a few related code smells that you definitely want to avoid in addition to the "catch everything everywhere" smell.
"catch, log, rethrow": if you want scoped based logging, then write a class that emits a log statement in its destructor when the stack is unrolling due to an exception (ala std::uncaught_exception()). All that you need to do is declare a logging instance in the scope that you are interested in and, voila, you have logging and no unnecessary try/catch logic.
"catch, throw translated": this usually points to an abstraction problem. Unless you are implementing a federated solution where you are translating several specific exceptions into one more generic one, you probably have an unnecessary layer of abstraction... and don't say that "I might need it tomorrow".
"catch, cleanup, rethrow": this is one of my pet-peeves. If you see a lot of this, then you should apply Resource Acquisition is Initialization techniques and place the cleanup portion in the destructor of a janitor object instance.
I consider code that is littered with try/catch blocks to be a good target for code review and refactoring. It indicates that either exception handling is not well understood or the code has become an amœba and is in serious need of refactoring.
Because the next question is "I've caught an exception, what do I do next?" What will you do? If you do nothing - that's error hiding and the program could "just not work" without any chance to find what happened. You need to understand what exactly you will do once you've caught the exception and only catch if you know.
You don't need to cover every block with try-catches because a try-catch can still catch unhandled exceptions thrown in functions further down the call stack. So rather than have every function have a try-catch, you can have one at the top level logic of your application. For example, there might be a SaveDocument() top-level routine, which calls many methods which call other methods etc. These sub-methods don't need their own try-catches, because if they throw, it's still caught by SaveDocument()'s catch.
This is nice for three reasons: it's handy because you have one single place to report an error: the SaveDocument() catch block(s). There's no need to repeat this throughout all the sub-methods, and it's what you want anyway: one single place to give the user a useful diagnostic about something that went wrong.
Two, the save is cancelled whenever an exception is thrown. With every sub-method try-catching, if an exception is thrown, you get in to that method's catch block, execution leaves the function, and it carries on through SaveDocument(). If something's already gone wrong you likely want to stop right there.
Three, all your sub-methods can assume every call succeeds. If a call failed, execution will jump to the catch block and the subsequent code is never executed. This can make your code much cleaner. For example, here's with error codes:
int ret = SaveFirstSection();
if (ret == FAILED)
{
/* some diagnostic */
return;
}
ret = SaveSecondSection();
if (ret == FAILED)
{
/* some diagnostic */
return;
}
ret = SaveThirdSection();
if (ret == FAILED)
{
/* some diagnostic */
return;
}
Here's how that might be written with exceptions:
// these throw if failed, caught in SaveDocument's catch
SaveFirstSection();
SaveSecondSection();
SaveThirdSection();
Now it's much clearer what is happening.
Note exception safe code can be trickier to write in other ways: you don't want to leak any memory if an exception is thrown. Make sure you know about RAII, STL containers, smart pointers, and other objects which free their resources in destructors, since objects are always destructed before exceptions.
Herb Sutter wrote about this problem here. For sure worth reading.
A teaser:
"Writing exception-safe code is fundamentally about writing 'try' and 'catch' in the correct places." Discuss.
Put bluntly, that statement reflects a fundamental misunderstanding of exception safety. Exceptions are just another form of error reporting, and we certainly know that writing error-safe code is not just about where to check return codes and handle error conditions.
Actually, it turns out that exception safety is rarely about writing 'try' and 'catch' -- and the more rarely the better. Also, never forget that exception safety affects a piece of code's design; it is never just an afterthought that can be retrofitted with a few extra catch statements as if for seasoning.
As stated in other answers, you should only catch an exception if you can do some sort of sensible error handling for it.
For example, in the question that spawned your question, the questioner asks whether it is safe to ignore exceptions for a lexical_cast from an integer to a string. Such a cast should never fail. If it did fail, something has gone terribly wrong in the program. What could you possibly do to recover in that situation? It's probably best to just let the program die, as it is in a state that can't be trusted. So not handling the exception may be the safest thing to do.
If you always handle exceptions immediately in the caller of a method that can throw an exception, then exceptions become useless, and you'd better use error codes.
The whole point of exceptions is that they need not be handled in every method in the call chain.
The best advice I've heard is that you should only ever catch exceptions at points where you can sensibly do something about the exceptional condition, and that "catch, log and release" is not a good strategy (if occasionally unavoidable in libraries).
I was given the "opportunity" to salvage several projects and executives replaced the entire dev team because the app had too many errors and the users were tired of the problems and run-around. These code bases all had centralized error handling at the app level like the top voted answer describes. If that answer is the best practice why didn't it work and allow the previous dev team to resolve issues? Perhaps sometimes it doesn't work? The answers above don't mention how long devs spend fixing single issues. If time to resolve issues is the key metric, instrumenting code with try..catch blocks is a better practice.
How did my team fix the problems without significantly changing the UI? Simple, every method was instrumented with try..catch blocked and everything was logged at the point of failure with the method name, method parameters values concatenated into a string passed in along with the error message, the error message, app name, date, and version. With this information developers can run analytics on the errors to identify the exception that occurs the most! Or the namespace with the highest number of errors. It can also validate that an error that occurs in a module is properly handled and not caused by multiple reasons.
Another pro benefit of this is developers can set one break-point in the error logging method and with one break-point and a single click of the "step out" debug button, they are in the method that failed with full access to the actual objects at the point of failure, conveniently available in the immediate window. It makes it very easy to debug and allows dragging execution back to the start of the method to duplicate the problem to find the exact line. Does centralized exception handling allow a developer to replicate an exception in 30 seconds? No.
The statement "A method should only catch an exception when it can handle it in some sensible way." This implies that developers can predict or will encounter every error that can happen prior to release. If this were true a top level, app exception handler wouldn't be needed and there would be no market for Elastic Search and logstash.
This approach also lets devs find and fix intermittent issues in production! Would you like to debug without a debugger in production? Or would you rather take calls and get emails from upset users? This allows you to fix issues before anyone else knows and without having to email, IM, or Slack with support as everything needed to fix the issue is right there. 95% of issues never need to be reproduced.
To work properly it needs to be combined with centralized logging that can capture the namespace/module, class name, method, inputs, and error message and store in a database so it can be aggregated to highlight which method fails the most so it can be fixed first.
Sometimes developers choose to throw exceptions up the stack from a catch block but this approach is 100 times slower than normal code that doesn't throw. Catch and release with logging is preferred.
This technique was used to quickly stabilize an app that failed every hour for most users in a Fortune 500 company developed by 12 Devs over 2 years. Using this 3000 different exceptions were identified, fixed, tested, and deployed in 4 months. This averages out to a fix every 15 minutes on average for 4 months.
I agree that it is not fun to type in everything needed to instrument the code and I prefer to not look at the repetitive code, but adding 4 lines of code to each method is worth it in the long run.
I agree with the basic direction of your question to handle as many exceptions as possible at the lowest level.
Some of the existing answer go like "You don't need to handle the exception. Someone else will do it up the stack." To my experience that is a bad excuse to not think about exception handling at the currently developed piece of code, making the exception handling the problem of someone else or later.
That problem grows dramatically in distributed development, where you may need to call a method implemented by a co-worker. And then you have to inspect a nested chain of method calls to find out why he/she is throwing some exception at you, which could have been handled much easier at the deepest nested method.
The advice my computer science professor gave me once was: "Use Try and Catch blocks only when it's not possible to handle the error using standard means."
As an example, he told us that if a program ran into some serious issue in a place where it's not possible to do something like:
int f()
{
// Do stuff
if (condition == false)
return -1;
return 0;
}
int condition = f();
if (f != 0)
{
// handle error
}
Then you should be using try, catch blocks. While you can use exceptions to handle this, it's generally not recommended because exceptions are expensive performance wise.
If you want to test the outcome of every function, use return codes.
The purpose of Exceptions is so that you can test outcomes LESS often. The idea is to separate exceptional (unusual, rarer) conditions out of your more ordinary code. This keeps the ordinary code cleaner and simpler - but still able to handle those exceptional conditions.
In well-designed code deeper functions might throw and higher functions might catch. But the key is that many functions "in between" will be free from the burden of handling exceptional conditions at all. They only have to be "exception safe", which does not mean they must catch.
I would like to add to this discussion that, since C++11, it does make a lot of sense, as long as every catch block rethrows the exception up until the point it can/should be handled. This way a backtrace can be generated. I therefore believe the previous opinions are in part outdated.
Use std::nested_exception and std::throw_with_nested
It is described on StackOverflow here and here how to achieve this.
Since you can do this with any derived exception class, you can add a lot of information to such a backtrace!
You may also take a look at my MWE on GitHub, where a backtrace would look something like this:
Library API: Exception caught in function 'api_function'
Backtrace:
~/Git/mwe-cpp-exception/src/detail/Library.cpp:17 : library_function failed
~/Git/mwe-cpp-exception/src/detail/Library.cpp:13 : could not open file "nonexistent.txt"
I feel compelled to add another answer although Mike Wheat's answer sums up the main points pretty well. I think of it like this. When you have methods that do multiple things you are multiplying the complexity, not adding it.
In other words, a method that is wrapped in a try catch has two possible outcomes. You have the non-exception outcome and the exception outcome. When you're dealing with a lot of methods this exponentially blows up beyond comprehension.
Exponentially because if each method branches in two different ways then every time you call another method you're squaring the previous number of potential outcomes. By the time you've called five methods you are up to 256 possible outcomes at a minimum. Compare this to not doing a try/catch in every single method and you only have one path to follow.
That's basically how I look at it. You might be tempted to argue that any type of branching does the same thing but try/catches are a special case because the state of the application basically becomes undefined.
So in short, try/catches make the code a lot harder to comprehend.
Besides the above advice, personally I use some try+catch+throw; for the following reason:
At boundary of different coder, I use try + catch + throw in the code written by myself, before the exception being thrown to the caller which is written by others, this gives me a chance to know some error condition occured in my code, and this place is much closer to the code which initially throw the exception, the closer, the easier to find the reason.
At the boundary of modules, although different module may be written my same person.
Learning + Debug purpose, in this case I use catch(...) in C++ and catch(Exception ex) in C#, for C++, the standard library does not throw too many exception, so this case is rare in C++. But common place in C#, C# has a huge library and an mature exception hierarchy, the C# library code throw tons of exception, in theory I(and you) should know every exceptions from the function you called, and know the reason/case why these exception being thrown, and know how to handle them(pass by or catch and handle it in-place)gracefully. Unfortunately in reality it's very hard to know everything about the potential exceptions before I write one line of code. So I catch all and let my code speak aloud by logging(in product environment)/assert dialog(in development environment) when any exception really occurs. By this way I add exception handling code progressively. I know it conflit with good advice but in reality it works for me and I don't know any better way for this problem.
You have no need to cover up every part of your code inside try-catch. The main use of the try-catch block is to error handling and got bugs/exceptions in your program. Some usage of try-catch -
You can use this block where you want to handle an exception or simply you can say that the block of written code may throw an exception.
If you want to dispose your objects immediately after their use, You can use try-catch block.

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.

When to use assertion over exceptions in domain classes

Are there any situations when you would use assertion instead of exceptions-handling inside domain classes...
Use exceptions for parameter validation and other checks which verify that the users of you classes use them as intended.
Use assertions for internal consistency checks, i.e. to indicate you screwed up, not the user of your class.
Thus, if users of your class see an assertion failure, they know it is (probably) an internal error in your code, not in their use of your code. On the other hand, if the get parameter validation exception, they know it's their fault.
Never. Assertions are not a valid form of error-handling. Use them to assist in identifying program errors during testing.
An assertion reflects a state that should not ever occur and was not expected, where the application cannot continue executing for one reason or another, whereas an exception indicates a state that is not considered "normal", but that was not unexpected, and from which it might be possible to recover.
As an example, if I allocate space on the heap, and this allocation fails, then I can't continue working, so I assert that the address returned is valid; where it is invalid, the assertion fails, and the program fails with it.
On the other hand, if I open a file for reading, and it doesn't exist, then it might be possible to recover from the situation, in which case an exception is thrown (and caught, and handled as far as possible).
In general, assertions are most useful during the debugging phase, whereas exceptions are considered part of regular program flow and error handling. The general consensus is that assertions should be disabled in production code (to shield users from apparent crashes), whereas I have read a school of thought that argues this is counter-productive, and that the user should see the assertion failure, so that they can properly report the problem.
Personally, I sometimes combine the two techniques; usually, if I'm catching an exception that I do not believe could be thrown. Taking the example above, if I check the file's existence before attempting to open it, then I do not expect an exception to be thrown, and if one is, then I tend to deal with this by raising an assertion in the relevant catch block. I find this a particularly useful technique in Java, where such exceptions are fully checked.

Are exceptions really for exceptional errors? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
It's my understanding that common wisdom says to only use exceptions for truly exceptional conditions (In fact, I've seen that statement here at SO several times).
However, Krzysztof Cwalina says:
One of the biggest misconceptions about exceptions is that they are for “exceptional conditions.” The reality is that they are for communicating error conditions. From a framework design perspective, there is no such thing as an “exceptional condition”. Whether a condition is exceptional or not depends on the context of usage, --- but reusable libraries rarely know how they will be used. For example, OutOfMemoryException might be exceptional for a simple data entry application; it’s not so exceptional for applications doing their own memory management (e.g. SQL server). In other words, one man’s exceptional condition is another man’s chronic condition.
He then also goes on to say that exceptions should be used for:
Usage errors
Program errors
System failures
Considering Krzysztof Cwalina is the PM for the CLR team at MS I ask: What do you think of his statement?
This sounds over-simplistic, but I think it makes sense to simply use exceptions where they are appropriate. In languages like Java and Python, exceptions are very common, especially in certain situations. Exceptions are appropriate for the type of error you want to bubble up through a code path and force the developer to explicitly catch. In my own coding, I consider the right time to add an exception when the error either can't be ignored, or it's simply more elegant to throw an exception instead of returning an error value to a function call etc.
Some of the most appropriate places for exceptions that I can think of offhand:
NotImplementedException - very appropriate way of designating that a particular
method or function isn't available, rather than simply returning without doing
anything.
OutOfMemory exceptions - it's difficult to imagine a better way of handling this
type of error, since it represents a process-wide or OS-wide memory allocation
failure. This is essential to deal with, of course!
NullPointerException - Accessing a null variable is a programmer mistake, and IMO
this is another good place to force an error to bubble to the surface
ArrayIndexException - In an unforgiving language like C, buffer overflows
are disastrous. Nicer languages might return a null value of some type, or in
some implementations, even wrap around the array. In my opinion, throwing an
exception is a much more elegant response.
This is by no means a comprehensive list, but hopefully it illustrates the point. Use exceptions where they are elegant and logical. As always with programming, the right tool for the right job is good advice. There's no point going exception-crazy for nothing, but it's equally unwise to completely ignore a powerful and elegant tool at your disposal.
For people who write frameworks, perhaps it's interesting.
For the rest of us, it's confusing (and possibly useless.) For ordinary applications, exceptions have to be set aside as "exceptional" situations. Exceptions interrupt the ordinary sequential presentation of your program.
You should be circumspect about breaking the ordinary top-to-bottom sequential processing of your program. The exception handling is -- intentionally -- hard to read. Therefore, reserve exceptions for things that are outside the standard scenarios.
Example: Don't use exceptions to validate user input. People make input mistakes all the time. That's not exceptional, that's why we write software. That's what if-statements are for.
When your application gets an OutOfMemory exception, there's no point in catching it. That's exceptional. The "sequential execution" assumption is out the window. Your application is doomed, just crash and hope that your RDBMS transaction finishes before you crash.
It is indeed difficult to know what exactly construes an "exceptional condition" which warrants the use of an exception in a program.
One instance that is very helpful for using communicating the cause of errors. As the quote from Krzysztof Cwalina mentions:
One of the biggest misconceptions
about exceptions is that they are for
“exceptional conditions.” The reality
is that they are for communicating
error conditions.
To give a concrete example, say we have a getHeader(File f) method that is reading some header from a file and returns a FileHeader object.
There can be several problems which can arise from trying to read data from a disk. Perhaps the file specified doesn't exist, file contains data that can't be read, unexpected disk access errors, running out of memory, etc. Having multiple means of failure means that there should be multiple ways to report what went wrong.
If exceptions weren't used, but there was a need to communicate the kind of error that occurred, with the current method signature, the best we can do is to return a null. Since getting a null isn't very informative, the best communication we get from that result is that "some kind of error happened, so we couldn't continue, sorry." -- It doesn't communicate the cause of the error.
(Or alternatively, we may have class constants for FileHeader objects which indicate FileNotFound conditions and such, emulating error codes, but that really reeks of having a boolean type with TRUE, FALSE, FILE_NOT_FOUND.)
If we had gotten a FileNotFound or DeviceNotReady exception (hypothetical), at least we know what the source of the error was, and if this was an end user application, we could handle the error in ways to solve the problem.
Using the exception mechanism gives a means of communication that doesn't require a fallback to using error codes for notification of conditions that aren't within the normal flow of execution.
However, that doesn't mean that everything should be handled by exceptions. As pointed out by S.Lott:
Don't use exceptions to validate user
input, for example. People make
mistakes all the time. That's what
if-statements are for.
That's one thing that can't be stressed enough. One of the dangers of not knowing when exactly to use exceptions is the tendency to go exception-happy; using exceptions where input validation would suffice.
There's really no point in defining and throwing a InvalidUserInput exception when all that is required to deal in such a situation is to notify the user of what is expected as input.
Also, it should be noted that user input is expected to have faulty input at some point. It's a defensive measure to validate input before handing off input from the outside world to the internals of the program.
It's a little bit difficult to decide what is exceptional and what is not.
Since I usually program in Python, and in that language exceptions are everywhere, to me an exception may represent anything from a system error to a completely legitimate condition.
For example, the "pythonic" way to check if a string contains an integer is to try int(theString) and see if it raises an exception. Is that an "exceptional error"?
Again, in Python the for loop is always thought of as acting on an iterator, and an iterator must raise a 'StopIteration' exception when it finishes its job (the for loop catches that exception). Is that "exceptional" by any means?
I think the closer to the ground are you are the less appropriate exceptions as a means of error communication become. At a higher abstraction such as in Java or .net, an exception may make for an elegant way to pass error messages to your callers. This however is not the case in C. This is also a framework vs api design decision.
If you practice "tell, don't ask" then an exception is just the way a program says "I can't do that". It is "exceptional" in that you say "do X" and it cannot do X. A simple error-handling situation. In some languages it is quite common to work this way, in Java and C++ people have other opinions because exceptions become quite costly.
General: exception just means "I can't"
Pragmatic: ... if you can afford to work that way in your language.
Citizenship: ... and your team allows it.
Here is the definition for exception: An exception is an event, which occurs during the execution of a program, that disrupts the normal flow of the program's instructions.
Therefore, to answer your question, no. Exceptions are for disruptive events, which may or may not be exceptional. I love this definition, it's simple and works every time - if you buy into exceptions like I do. E.g., a user submits an incorrect un/pw, or you have an illegal argument/bad user input. Throwing an exception here is the most straightforward way of solving these problems, which are disruptive, but not exceptional, nor even unanticipated.
They probably should have been called disruptions, but that boat has sailed.
I think there are a couple of good reasons why exceptions should be used to catch unexpected problems.
Firstly, they create an object to encapsulate the exception, which by definition must make it a lot more expensive than processing a simple if-statement. As a Java example, you should call File.exists() rather than routinely expecting and handling a FileNotFoundException.
Secondly, exceptions that are caught outside the current method (or maybe even class) make the code much harder to read than if the handling is all there in in the one method.
Having said that, I personally love exceptions. They relieve you of the need of explicitly handling all of those may-happen-but-probably-never-will type errors, which cause you to repetitively write print-an-error-and-abort-on-non-zero-return-code handling of every method call.
My bottom line is... if you can reasonably expect it to happen then it's part of your application and you should code for it. Anything else is an exception.
I've been wondering about this myself. What do we mean by "exceptional"? Maybe there's no strict definition, but are there any rules of thumb that we can use to decide what's exceptional, in a given context?
For example, would it be fair to say that an "exceptional" condition is one that violates the contract of a function?
KCwalina has a point.
It will be good to identify cases where the code will fail (upto a limit)
I agree with S.Lott that sometimes validating is better than to throw Exception.
Having said that, OutOfMemory is not what you might expect in your application (unless it is allocating a large memory & needs memory to go ahead).
I think, it depends on the domain of the application.
The statement from Krzysztof Cwalina is a little misleading. The original statement refers 'exceptional conditions', for me it is natural that I am the one who defines what's exceptional or not. Nevertheless, I think the message passed through OK, since I think we are all talking about 'developer' exceptions.
Exceptions are great for communication, but with a little hierarchy design they are also great for some separation of concerns, specially between layers (DAO, Business, etc). Of course, this is only useful if you treat these exceptions differently.
A nice example of hierarchy is spring's data access exception hierarchy.
I think he is right. Take a look at number parsing in java. You cant even check input string before parsing. You are forced to parse and retrieve NFE if something went wrong. Is parse failure something exceptional? I think no.
I certainly believe exceptions should be used only if you have an exceptional condition.
The trouble is in the definition of "exceptional". Here is mine:
A condition is exceptional if it is outside the assumed normal
behaviour of the part of the system that raises the exception.
This has some implications:
Exceptional depends on your assumptions. If a function assumes that it is passed valid parameters, then throwing an IllegalArgumentException is OK. However if a function's contract says that it will correct input errors in input in some way, then this usage is "normal" and it shouldn't throw an exception on an input error.
Exceptional depends on sub-system layering. A network IO function could certainly raise an exception if the network is discommented, as it assumes a valid connection. A ESB-based message broker however would be expected to handle dropped connections, so if it used such a network IO function internally then it would need to catch and handle the error appropriately. In case it isn't obvious, try/catch is effectively equivalent to a subsystem saying "a condition which is exceptional for one of my components is actually considered normal by me, so I need to handle it".
The saying that exceptions should be used for exceptional circumstances is used in "Effective Java Second Edition": one of the best java books.
The trouble is that this is taken out of context. When the author states that exceptions should be exceptional, he had just shown an example of using exceptions to terminate a while loop - a bad exception use. To quote:
exceptions are, as their name implies, to
be used only for exceptional conditions; they should never be used for ordinary
control flow.
So it all depends on your definition of "exception condition". Taken out of context you can imply that it should very rarely be used.
Using exceptions in place of returning error codes is good, while using them in order to implement a "clever" or "faster" technique is not good. That's usually what is meant by "exceptional condition".
Checked exception - minor errors that aren't bugs and shouldn't halt execution. ex. IO or file parsing
Unchecked exception - programming "bug" that disobeys a method contract - ex. OutOfBoundsException. OR a error that makes continuing of execution a very bad idea - ex IO or file parsing of a very important file. Perhaps a config file.
What it comes down to is what tool is needed to do the job.
Exceptions are a very powerful tool. Before using them ask if you need this power and the complexity that comes with it.
Exceptions may appear simple, because you know that when the line with the exception is hit everything comes to a halt. What happens from here though?
Will an uncaught exception occur?
Will the exception be caught by global error handling?
Will the exception be handled by more nested and detailed error handling?
You have to know everything up the stack to know what that exception will do. This violates the concept of independence. That method now is dependent on error handling to do what you expect it to.
If I have a method I shouldn't care what is outside of that method. I should only care what the input is, how to process it, and how to return the response.
When you use an exception you are essentially saying, I don't care what happens from here, something went wrong and I don't want it getting any worse, do whatever needs to be done to mitigate the issue.
Now if you care about how to handle the error, you will do some more thinking and build that into the interface of the method e.g. if you are attempting to find some object possibly return the default of that object if one can't be found rather than throwing some exception like "Object not found".
When you build error handling into your methods interface, not only is that method's signature more descriptive of what it can do, but it places the responsibility of how to handle the error on the caller of the method. The caller method may be able to work through it or not, and it would report again up the chain if not. Eventually you will reach the application's entry point. Now it would be appropriate to throw an exception, since you better have a good understanding of how exceptions will be handled if you're working with the applications public interface.
Let me give you an example of my error handling for a web service.
Level 1. Global error handling in global.asax - That's the safety net to prevent uncaught exceptions. This should never intentionally be reached.
Level 2. Web service method - Wrapped in a try/catch to guarantee it will always comply with its json interface.
Level 3. Worker methods - These get data, process it, and return it raw to the web service method.
In the worker methods it's not right to throw an exception. Yes I have nested web service method error handling, but that method can be used in other places where this may not exist.
Instead if a worker method is used to get a record and the record can't be found, it just returns null. The web service method checks the response and when it finds null it knows it can't continue. The web service method knows it has error handling to return json so throwing an exception will just return the details in json of what happened. From a client's perspective it's great that it got packaged into json that can be easily parsed.
You see each piece just knows what it needs to do and does it. When you throw an exception in the mix you hijack the applications flow. Not only does this lead to hard to follow code, but the response to abusing exceptions is the try/catch. Now you are more likely to abuse another very powerful tool.
All too often I see a try/catch catching everything in the middle of an a application, because the developer got scared a method they use is more complex than it appears.