Where is the proper place to handle thrown exception from lower layers.. inside the class or at the possible toppest level? OR it depends to the use case?
You can take a look at this post:
In particular it is now possible (and considered good practice) to set up a top-level exception handler that will handle any unexpected exception on the main thread in a Windows application. This means that it is no longer necessary to have exception handlers in every routine.
You may also look at How to implement top level exception handling?
And one link for exception handling in Java http://onjava.com/pub/a/onjava/2003/11/19/exceptions.html
So, as a general answer to your question: I would say that yes it depends on the use case (is it just your simple short script or a full-fledged application), but you should try to do the exception handling at the highest possible level, and while doing that do keep in mind the "technicality" of the message you present to your users (trust me, a message "error 31231241 in main thread" doesn't improve user friendlines of your application).
edit:
As Steve McConnell also states in his famous Code Complete 2 book, one should Throw exceptions on the right level of abstraction - for example if you have a getUser() method and you return IOException then that would be very bad. But yes, I think that's commmon sense. Also, he says that one should write a function in such manner that if some other function sends it "garbage", it should not cause a crash of the whole program.
Also, he is in favor of using assertions, and he says: Use error handling code for the conditions you expect to occur; use assertions for conditions that should never occur.
Finally, the states that while addressing the errors you should keep in mind the two approaches: robustness and correctness. The story he tells in the book for this example is very vivid and stayed in my head long after I've read it. Consider having a "Text editing application" and take into account the correctness of the data presented. Imagine few pixels "go wild" (you misscalculate them, or sth like that) - for sure you wouldn't consider to force close the application if something like that happens and this is called robustness (continue operating). But, imagine now that you're making an X-ray manipulation application- in this case any "wierd data" should (as McConnell suggest) cause the critical error message and it is said that you're striving for correctness in your applicaiton.
P.S. pardon for the CC2 part, but I just love that book and think every developer should read it (at least once).
This is just a general design question. If you are developing a business component or service, (e.g. an object/service that exposes a relatively simple interface for handling billing transactions), what are some good ways to handle business-related errors?
Say the component/service must integrate with a few different external web services that all report back different errors, and must also do some database work on your side. There are many different things that can go wrong, both network/database-wise and business rule-wise. Would it be better to try to catch all types of errors within the component and report them back to the caller using an error-code scheme, or try to wrap all errors into various types of exceptions and throw them on to the caller.
This seems to be a struggle, because it gets awkward to deal with the business rule checks using exceptions, and I've read in several places to avoid using exceptions to control "non-exceptional" or business-logic flows. I feel that "exceptional" is often a debatable term, and it gets sticky trying to keep different cases defined as "exceptional" vs. "non-exceptional." (e.g. if your business logic checks for spending limits, age limitations, etc.). At the same time, using an error-code scheme is also awkward, because the caller might choose to ignore the error codes.
Any tips or references would be appreciated!
I'd go for the error code scheme, because you said "many different things that can go wrong". You might want to have a scheme that returns a List of Error objects, where Error would encapsulate the code, explanation, original data, etc.
An exception can only tell one thing that's wrong, and it should be of an "exceptional" nature, not a run-of-the-mill problem.
Or perhaps a hybrid where you throw an exception that has a List of Error objects as a private data member and an access method that lets you iterate over the errors.
Business related errors should not be exeptions. Exceptions are there if there is an event in the program that the program is not designed to handle or completly unforseen.
To this end, if you anticipate a large number of different exceptions, by all means implement some useful numbering scheme. Here I would recommend a guid for the reason of component reuse. Every component should expose some interface to query the list of possible exception numbers (this can then be added to a data store for documentation). Also as you reuse components, error codes will not conflict.
User or business data errors on the other hand almost warrant some numbering scheme. There is almost no way to anticipate all the silly things a user is capable of. However, I would strongly discourage formal language exceptions in favour of some custom error object. Language exceptions may incur significant overhead, or require specialized handling to prevent them from propogating up the call stack. A business error object may very well be a nice way to go.
Services are borderline, especially if they have to be hit from various languages that may not handle SOAP exceptions properly. There are also security concerns if it's on the WWW.
If it's not a service, is internal, and/or will be accessed by clients in known languages, use exceptions to handle failure conditions. Clients are not guaranteed to check error codes.
See
http://msdn.microsoft.com/en-us/library/ms229030.aspx
for a great discussion of this. (It's also in the book Framework Design Guidelines.)
There's absolutely nothing that could prevent you from making both business rules and technical rules violations exceptions. I'd use exceptions in two cases:
Precondition violation. If your function's specification says "the amount spent should not exceed the limit for this type of account", and user, knowing this, specifies greater limit anyway, throw the exception right into him!
Postcondition violation. If all preconditions are met, but due to unexpected denial (database connection, for example; or completion of the transaction violates anti-monopoly law) you can't supply the correct result, do not supply it. Throw an exception.
Since all business logic probably is within one component and doesn't rely on anything else, case 2 for business exceptions is quite rare. And what falls into case 1 should be checked for in the front-end application. This makes me think that the approach of not throwing business-logic exceptions is not that you "should not do", but likely "you mostly don't need to".
Anyway, from the perspective of the language you're programming, it hardly notices the difference between "technical" and "business" exceptions, so it'll handle them all correctly. Second, exceptions are caught somewhere. I guess, that, from architector's point of view, business and technical exceptions will be caught in the different components. Of course, unless they're effectively uncaught, merely displaying error messages without programmatical handling falls into this category. So the use of the same mechanism won't make you mix these errors.
So, my point is, that if you chose not to repulse exceptions as programming concept, you may use them for business logic as well.
I see a lot of code written where an exception is thrown if a parameter is not in the right form, or whatever. Basically "throw new ...".
What is the benefit of this? The exception can be avoided by checking the parameters (Eg if null, write message back to webpage/winform). Why is this approach not used when an exception is expensive?
Thanks
A few points are worth making here:
First, your supposition that exceptions are expensive is generally untrue - exceptions are, well ... exceptional. They shouldn't be occurring often enough to have any meaningful effect on program performance. And if you are seeing enough exceptions that performance is a problem then you have bigger fish to fry.
Second, a well written class, function or module program should be able to detect and handle invalid input somewhat gracefully. It helps the maintainers and debuggers of the code locate the problems as close to their introduction as possible. If arguments are not checked, they can often result in a failure much later in the code - far removed from the actual error. Debugging such problems can be very painful.
Third, you assume that all code is aware of the context in which it is executed. A method may be deep in a framework or library and have no knowledge of whether it is running in a web application, console app, NT service, etc. Besides, it'a terrible practice to pepper logic to display information about invalid arguments throughout the body of your code - that responsibility should be centralized and controlled - otherwise you UI could easily become a mess of errors interspersed with actual presentation content.
Finally, exceptions allow a program to sometimes handle and recover from a problem rather than exposing it to the user. Don't diminish this capability by directly displaying errors immediately when they occur. Now, granted, most often invalid arguments are a symptom of a programming defect (rather than an environmental or configuration issue) - and so in most cases they can't be handled. But, then again, sometimes they can be handled.
For example, if you're writing a library to be used by code you don't know about or doesn't exist yet, how that error is handled is down to the code that is making the call.
So throwing an exception is a natural thing to do. Allows you to leave the decision on how to handle that error scenario to the caller/consumer.
Throwing an exception:
makes it clear to other programmers that the situation is exceptional
allows software calling the method involved to clearly handle the problem
shows tools and the compiler that the situation is exceptional so that they can assist the programmer
allows information to be passed to handling routines in the exception object itself
Printing strings - well - doesn't, really.
In terms of the 'expense' of an exception, exceptions should only be thrown in exceptional circumstances, i.e. rarely and as part of processing errors - I personally have not come across a situation where the 'expense' of an exception is a problem. More discussion on that point in this question.
This is known as Design by Contract.
The basic idea of Design by Contract is that objects have contracts between them, and if a caller does not fulfill the contract the receiver should fail with an exception rather than trying to guess the callers intention. At the end of the day, this leads to more stable software (in particular when more than one person is writing on project, since then the contract also become contracts between programmers).
PS: An important issue of Design by Contract that is often forgotten is the following. It must be possible for the client to know whether it fulfills the contract or not. So eg, if the contract of a stack is that client may only pop when the stack is not empty there must be an isEmpty method to check that and clients should use that method before calling pop. So this is why code that uses Design by Contract is cluttered with exceptions that are nevertheless never thrown.
It is better to throw an exception if the code will be compiled into a library and reused in multiple applications. In that case the client that calls into the library should handle the exceptions appropriately and report a user friendly message.
There are two main reasons I throw exceptions instead of writing an error message to standard out.
Debugging is easier - I know if the program has exited because of an error. Also, since exceptions in Java can be subclassed, I know exactly what type of error has occurred.
If you write an API, and then decide you want a GUI front-end, perhaps you want to take those exceptions and display them in a message dialog instead of writing them to standard out.
Generally and language-agnostically speaking, it is not correct assumption that exceptions are expensive. It depends on many factors.
Generally, exception is a generic way to signal an error condition and it is independent of any form of presentation. Sending out a page with error message would make the error reporting too tightly coupled with presentation, with UI. It is usually not a good idea in terms of flexible and scalable design.
The question is general and language-agnostic, thus the answer does not go deeply into details.
By the way, depending on a programming language, design of error handling, and number of other factors, approaches can be different. However, it's a good idea to learn about various options:
in C++, in Boost project, error handling guidelines say:
Don't worry too much about the what()
message. It's nice to have a message
that a programmer stands a chance of
figuring out, but you're very unlikely
to be able to compose a relevant and
user-comprehensible error message at
the point an exception is thrown (...)
Krzysztof Cwalina recommends a set of very useful Design Guidelines for .NET but they are in fact language-agnostic like Should Exceptions Carry Error Code Information
Given the guidelines above, after a while of consideration, it is not that clear what such error web page should display, what level of information, very technical or more user-friendly. Using exceptions, it gives more flexibility on various levels of the system as one of rules it catch when you need to handle (i.e. display error) ignore otherwise
Exceptions are, in most environments, easier to write tests for than is stuff written to the console:
it "should reject a negative initial balance" do
Account.new(-1).should raise_error(ArgumentError, "Invalid balance: -1")
end
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 1 year ago.
Improve this question
Google's Go language has no exceptions as a design choice, and Linus of Linux fame has called exceptions crap. Why?
Exceptions make it really easy to write code where an exception being thrown will break invariants and leave objects in an inconsistent state. They essentially force you to remember that most every statement you make can potentially throw, and handle that correctly. Doing so can be tricky and counter-intuitive.
Consider something like this as a simple example:
class Frobber
{
int m_NumberOfFrobs;
FrobManager m_FrobManager;
public:
void Frob()
{
m_NumberOfFrobs++;
m_FrobManager.HandleFrob(new FrobObject());
}
};
Assuming the FrobManager will delete the FrobObject, this looks OK, right? Or maybe not... Imagine then if either FrobManager::HandleFrob() or operator new throws an exception. In this example, the increment of m_NumberOfFrobs does not get rolled back. Thus, anyone using this instance of Frobber is going to have a possibly corrupted object.
This example may seem stupid (ok, I had to stretch myself a bit to construct one :-)), but, the takeaway is that if a programmer isn't constantly thinking of exceptions, and making sure that every permutation of state gets rolled back whenever there are throws, you get into trouble this way.
As an example, you can think of it like you think of mutexes. Inside a critical section, you rely on several statements to make sure that data structures are not corrupted and that other threads can't see your intermediate values. If any one of those statements just randomly doesn't run, you end up in a world of pain. Now take away locks and concurrency, and think about each method like that. Think of each method as a transaction of permutations on object state, if you will. At the start of your method call, the object should be clean state, and at the end there should also be a clean state. In between, variable foo may be inconsistent with bar, but your code will eventually rectify that. What exceptions mean is that any one of your statements can interrupt you at any time. The onus is on you in each individual method to get it right and roll back when that happens, or order your operations so throws don't effect object state. If you get it wrong (and it's easy to make this kind of mistake), then the caller ends up seeing your intermediate values.
Methods like RAII, which C++ programmers love to mention as the ultimate solution to this problem, go a long way to protect against this. But they aren't a silver bullet. It will make sure you release resources on a throw, but doesn't free you from having to think about corruption of object state and callers seeing intermediate values. So, for a lot of people, it's easier to say, by fiat of coding style, no exceptions. If you restrict the kind of code you write, it's harder to introduce these bugs. If you don't, it's fairly easy to make a mistake.
Entire books have been written about exception safe coding in C++. Lots of experts have gotten it wrong. If it's really that complex and has so many nuances, maybe that's a good sign that you need to ignore that feature. :-)
The reason for Go not having exceptions is explained in the Go language design FAQ:
Exceptions are a similar story. A
number of designs for exceptions have
been proposed but each adds
significant complexity to the language
and run-time. By their very nature,
exceptions span functions and perhaps
even goroutines; they have
wide-ranging implications. There is
also concern about the effect they
would have on the libraries. They are,
by definition, exceptional yet
experience with other languages that
support them show they have profound
effect on library and interface
specification. It would be nice to
find a design that allows them to be
truly exceptional without encouraging
common errors to turn into special
control flow that requires every
programmer to compensate.
Like generics, exceptions remain an
open issue.
In other words, they haven't yet figured out how to support exceptions in Go in a way that they think is satisfactory. They are not saying that Exceptions are bad per se;
UPDATE - May 2012
The Go designers have now climbed down off the fence. Their FAQ now says this:
We believe that coupling exceptions to a control structure, as in the try-catch-finally idiom, results in convoluted code. It also tends to encourage programmers to label too many ordinary errors, such as failing to open a file, as exceptional.
Go takes a different approach. For plain error handling, Go's multi-value returns make it easy to report an error without overloading the return value. A canonical error type, coupled with Go's other features, makes error handling pleasant but quite different from that in other languages.
Go also has a couple of built-in functions to signal and recover from truly exceptional conditions. The recovery mechanism is executed only as part of a function's state being torn down after an error, which is sufficient to handle catastrophe but requires no extra control structures and, when used well, can result in clean error-handling code.
See the Defer, Panic, and Recover article for details.
So the short answer is that they can do it differently using multi-value return. (And they do have a form of exception handling anyway.)
... and Linus of Linux fame has called exceptions crap.
If you want to know why Linus thinks exceptions are crap, the best thing is to look for his writings on the topic. The only thing I've tracked down so far is this quote that is embedded in a couple of emails on C++:
"The whole C++ exception handling thing is fundamentally broken. It's especially broken for kernels."
You'll note that he's talking about C++ exceptions in particular, and not exceptions in general. (And C++ exceptions do apparently have some issues that make them tricky to use correctly.)
My conclusion is that Linus hasn't called exceptions (in general) "crap" at all!
Exceptions are not bad per se, but if you know they are going to happen a lot, they can be expensive in terms of performance.
The rule of thumb is that exceptions should flag exceptional conditions, and that you should not use them for control of program flow.
I disagree with "only throw exceptions in an exceptional situation." While generally true, it's misleading. Exceptions are for error conditions (execution failures).
Regardless of the language you use, pick up a copy of Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries (2nd Edition). The chapter on exception throwing is without peer. Some quotes from the first edition (the 2nd's at my work):
DO NOT return error codes.
Error codes can be easily ignored, and often are.
Exceptions are the primary means of reporting errors in frameworks.
A good rule of thumb is that if a method does not do what its name suggests, it should be considered a method-level failure, resulting in an exception.
DO NOT use exceptions for the normal flow of control, if possible.
There are pages of notes on the benefits of exceptions (API consistency, choice of location of error handling code, improved robustness, etc.) There's a section on performance that includes several patterns (Tester-Doer, Try-Parse).
Exceptions and exception handling are not bad. Like any other feature, they can be misused.
From the perspective of golang, I guess not having exception handling keeps the compiling process simple and safe.
From the perspective of Linus, I understand that kernel code is ALL about corner cases. So it makes sense to refuse exceptions.
Exceptions make sense in code were it's okay to drop the current task on the floor, and where common case code has more importance than error handling. But they require code generation from the compiler.
For example, they are fine in most high-level, user-facing code, such as web and desktop application code.
Exceptions in and of themselves are not "bad", it's the way that exceptions are sometimes handled that tends to be bad. There are several guidelines that can be applied when handling exceptions to help alleviate some of these issues. Some of these include (but are surely not limited to):
Do not use exceptions to control program flow - i.e. do not rely on "catch" statements to change the flow of logic. Not only does this tend to hide various details around the logic, it can lead to poor performance.
Do not throw exceptions from within a function when a returned "status" would make more sense - only throw exceptions in an exceptional situation. Creating exceptions is an expensive, performance-intensive operation. For example, if you call a method to open a file and that file does not exist, throw a "FileNotFound" exception. If you call a method that determines whether a customer account exists, return a boolean value, do not return a "CustomerNotFound" exception.
When determining whether or not to handle an exception, do not use a "try...catch" clause unless you can do something useful with the exception. If you are not able to handle the exception, you should just let it bubble up the call stack. Otherwise, exceptions may get "swallowed" by the handler and the details will get lost (unless you rethrow the exception).
Typical arguments are that there's no way to tell what exceptions will come out of a particular piece of code (depending on language) and that they are too much like gotos, making it difficult to mentally trace execution.
http://www.joelonsoftware.com/items/2003/10/13.html
There is definitely no consensus on this issue. I would say that from the point of view of a hard-core C programmer like Linus, exceptions are definitely a bad idea. A typical Java programmer is in a vastly different situation, though.
Exceptions aren't bad. They fit in well with C++'s RAII model, which is the most elegant thing about C++. If you have a bunch of code already that's not exception safe, then they're bad in that context. If you're writing really low level software, like the linux OS, then they're bad. If you like littering your code with a bunch of error return checks, then they not helpful. If you don't have a plan for resource control when an exception is thrown (that C++ destructors provides) then they're bad.
A great use-case for exceptions is thus....
Say you are on a project and every controller (around 20 different major ones) extends a single superclass controller with an action method. Then every controller does a bunch of stuff different from each other calling objects B, C, D in one case and F, G, D in another case. Exceptions come to the rescue here in many cases where there was tons of return code and EVERY controller was handling it differently. I whacked all that code, threw the proper exception from "D", caught it in the superclass controller action method and now all our controllers are consistent. Previously D was returning null for MULTIPLE different error cases that we want to tell the end-user about but couldn't and I didn't want to turn the StreamResponse into a nasty ErrorOrStreamResponse object (mixing a data structure with errors in my opinion is a bad smell and I see lots of code return a "Stream" or other type of entity with error info embedded in it(it should really be the function returns the success structure OR the error structure which I can do with exceptions vs. return codes)....though the C# way of multiple responses is something I might consider sometimes though in many cases, the exception can skip a whole lot of layers(layers that I don't need to clean up resources on either).
yes, we have to worry about each level and any resource cleanup/leaks but in general none of our controllers had any resources to clean up after.
thank god we had exceptions or I would have been in for a huge refactor and wasted too much time on something that should be a simple programming problem.
Theoretically they are really bad. In perfect mathematical world you cannot get exception situations. Look at the functional languages, they have no side effects, so they virtually do not have source for unexceptional situations.
But, reality is another story. We always have situations that are "unexpected". This is why we need exceptions.
I think we can think of exceptions as of syntax sugar for ExceptionSituationObserver. You just get notifications of exceptions. Nothing more.
With Go, I think they will introduce something that will deal with "unexpected" situations. I can guess that they will try to make it sound less destructive as exceptions and more as application logic. But this is just my guess.
The exception-handling paradigm of C++, which forms a partial basis for that of Java, and in turn .net, introduces some good concepts, but also has some severe limitations. One of the key design intentions of exception handling is to allow methods to ensure that they will either satisfy their post-conditions or throw an exception, and also ensure that any cleanup which needs to happen before a method can exit, will happen. Unfortunately, the exception-handling paradigms of C++, Java, and .net all fail to provide any good means of handling the situation where unexpected factors prevent the expected cleanup from being performed. This in turn means that one must either risk having everything come to a screeching halt if something unexpected happens (the C++ approach to handling an exception occurs during stack unwinding), accept the possibility that a condition which cannot be resolved due to a problem that occurred during stack-unwinding cleanup will be mistaken for one which can be resolved (and could have been, had the cleanup succeeded), or accept the possibility that an unresolvable problem whose stack-unwinding cleanup triggers an exception that would typically be resolvable, might go unnoticed as code which handles the latter problem declares it "resolved".
Even if exception handling would generally be good, it's not unreasonable to regard as unacceptable an exception-handling paradigm that fails to provide a good means for handling problems that occur when cleaning up after other problems. That isn't to say that a framework couldn't be designed with an exception-handling paradigm that could ensure sensible behavior even in multiple-failure scenarios, but none of the top languages or frameworks can as yet do so.
I havent read all of the other answers, so this ma yhave already been mentioned, but one criticism is that they cause programs to break in long chains, making it difficult to track down errors when debugging the code. For example, if Foo() calls Bar() which calls Wah() which calls ToString() then accidentily pushing the wrong data into ToString() ends up looking like an error in Foo(), an almost completely unrelated function.
For me the issue is very simple. Many programmers use exception handler inappropriately. More language resource is better. Be capable to handle exceptions is good. One example of bad use is a value that must be integer not be verified, or another input that may divide and not be checked for division of zero... exception handling may be an easy way to avoid more work and hard thinking, the programmer may want to do a dirty shortcut and apply an exception handling... The statement: "a professional code NEVER fails" might be illusory, if some of the issues processed by the algorithm are uncertain by its own nature. Perhaps in the unknown situations by nature is good come into play the exception handler. Good programming practices are a matter of debate.
Exception not being handled is generally bad.
Exception handled badly is bad (of course).
The 'goodness/badness' of exception handling depends on the context/scope and the appropriateness, and not for the sake of doing it.
Okay, boring answer here. I guess it depends on the language really. Where an exception can leave allocated resources behind, they should be avoided. In scripting languages they just desert or overjump parts of the application flow. That's dislikable in itself, yet escaping near-fatal errors with exceptions is an acceptable idea.
For error-signaling I generally prefer error signals. All depends on the API, use case and severity, or if logging suffices. Also I'm trying to redefine the behaviour and throw Phonebooks() instead. The idea being that "Exceptions" are often dead ends, but a "Phonebook" contains helpful information on error recovery or alternative execution routes. (Not found a good use case yet, but keep trying.)