I want to know, is it a good practice to place complete code inside a try block or I should place only the code which I feel it will cause a specific exception?
And should I catch basic Exception always
Code 1: complete code in try block
myFunction(){
try{
.........
Code with chance of OneException
.............
}catch(OneException e){
............
}catch(Exception e){
..............
}
}
Code 2: Only the Code with chance of Exception in try block
myFunction(){
.......
try{
Code with chance of OneException
}catch(OneException e){
............
}
............
}
Code 3:Should I catch Exception always
myFunction(){
.......
try{
Code chance of OneException
}catch(OneException e){
............
}catch(Exception e){
..............
}
........
}
Out of this (code1, code2 and code3) which one is the best?
I'm mainly concern with java and C++ coding
Generally speaking, you should only catch exceptions you're interested in and which you can handle. That is...catch an exception where you can do something s.t. the user doesn't perceive the problem or when it is explicitly necessary to tell the user about the problem.
For all other exceptions, let them pop up with all their details (stacktrace etc..) which you obviously log. Note, obviously this doesn't mean the user should also see that exception output but rather a generic error.
Told this, I assume that when you write "Code chance of OneException" you know how to handle OneException, but not Exception, right? So then...only handle OneException.
Always catch exactly what you have to and no more. No matter how much we try, we cannot make our code completely "idiot proof". If someone passes you something which will cause some random error, then it is their job to handle it. If our code handles someone else's exception that has far too much risk of being an unexpected side-effect.
As far as what code to place where: code before the line which could throw the Exception will be run either way, so it does not really make sense to have it inside the try block and before the code which throws. Code after the potential exception should be placed between try and catch if and only if it depends on the exception generating code. So, if your database connection call can fail, place all of the database queries inside the try block.
Limiting the "time" spent in a try...catch makes it easier to read and less prone to accidental catching. I can't tell you how many hours have been lost because someone decided to catch an Exception which should have propagated.
a) It is bad practice, to place complete code inside a try block.
a1) Beside of catching exceptions, a try-block is a documentation where an exception might happen. So place it close to the cause, you have in mind.
a2) In bad circumstances, you have a file for reading, and add later one for writing, but your exception (FileNotFoundException) was written only with the first in mind. A lean scope around the problematic places will help you, identifying further problems.
b) Don't catch basic Exception for completeness or to avoid multiple catch blocks. If you want to write to a file, many things can go wrong: Missing permission, illegal file name, no space left on device, ... . If you present the user a generic Message ("Couldn't write file " + name), he doesn't know what to do. Be as specific as possible, and you can inform him, "Only 20 MB left on device " + devicename + "We need another 8 MB (28 MB in total); please free some space and repeat or choose a different device!"). If you catch "Exception", chances are high, that you're thinking of some exception, but another one occurs, and isn't handled correctly, because the catch-block wasn't written with that possibility in mind.
The best chance to find this exception is, to let it pop up, or, to log it, if the logs are controlled on a regular basis.
It can be a difference between developing an application, which is simply used by end users, or by developing an API, which is used by other developers.
In an API, you often want to wrap an exception into an own exception, to make it easier for users of your api to handle it, and if you have an uniform way to handle exceptions. If your code can throw many exceptions, and would lead to ugly client code, where your customer would need to specify a bunch of exceptions over and over again, you often wrap the exceptions and rethrow them:
try {
...
}
catch {FileNotFoundException fnfe}
{
throw new MyApiException (fnfe);
}
catch {PermissionDeniedException pde}
{
throw new MyApiException (pde);
}
catch {IOException ioe}
{
throw new MyApiException (ioe);
}
That way, your client can decide, how to handle the exception, and will find the specific type of exception, if interested, inside your exception.
As Landei points out, in Java 7 there will be a simplified technique, to catch multiple exceptions, but not only such with a common superclass, see this link here
Wrap the code at the point where you really can handle the exception, and where you can handle the error. If you can't handle the error in the function, then do no wrap the code in try/catch block.
I don't know for java, but in c++ you should catch by const reference :
try
{
// code that can throw an exception
}
catch ( const SomeExceptionType & error )
{
// handle the error
}
C++ isn't Java or C# or... where you need catch (or finally) clauses to clean up after yourself. In C++, RAII does that. Consequently, I rarely ever write try/catch statements in C++, to the point where I consider it a code smell.
So, rather than contemplating which style of code you should use in conjunction with try/catch, you should ask yourself whether you need that try/catch at all.
Related
While I regularly use try/catch, I haven't needed for finally or rethrow. In my quest to broaden my knowledge and potentially improve the apps I work on, how would one use the additional options? I primarily work in Lucee and usually refer to the documentation at cfdocs but specifically for this question cfdocs.org/cftry and the examples don't go into the finally or rethrow... or even throw for that matter (but I'm familiar with throw).
Sample code might help me more than just documentation alone on this.
A finally block is useful when you're managing resources, like a file handle. It can be used with or without a catch block. The example you'll usually see is closing a file handle:
var f = fileopen(filename, "r")
try {
// Some dubious code
} finally {
// f is freed, regardless of any exception thrown within the try block
fileclose(f);
}
The finally block is called regardless of whether an exception is thrown within the try block or not.
rethrow is handy if you ultimately want to bubble the exception up the callstack, but first do something with it. I often find myself logging an exception before rethrowing it to generate a generic error page:
try {
// Something sketchy
} catch (any e) {
writelog(type="Error", file="uhoh.log", text=e.message);
rethrow;
}
rethrow is also useful when you're dealing with weird ColdFusion exceptions that can only be identified by introspection, as opposed to catching them by type. Maybe you want to ignore a certain exception that is thrown whenever sketchy authentication code you didn't write (yeah, this is from experience) encounters an invalidated session, but bubble anything else up:
try {
// Hey, external code, is this user authenticated?
} catch (any e) {
if (e.id != MAGIC_NUMBER_TO_IGNORE)
rethrow;
}
A good resource, as usual, is Ben Nadel's ColdFusion blog.
I am reading literature on "C++ Exception Handling" (EH) from various resources. I have understood the concepts as well as the syntax. BUT On a larger scale I am confused .
We write code to execute it completely. It is expected that the written code will execute in known specific way(s). If some part of code throws exception and it is handled and the program continues execution. But from throw point to catch function some function(s) did not execute,normally they should have been, then how come the program can continue further as it is not completely executed.
I have come across statements that tells EH is used for error recovery.
But i need some concrete example to see what error recovery means / how it is done especially in C++ EH.
When an exception is thrown, execution does not continue from the point immediately after where the exception was thrown. Rather, execution is transferred back to the "nearest"1 catch block that can catch the type of exception that was thrown. After the code in that catch block executes, execution continues in whatever code comes after it, just like usual. That might (eventually) lead back to the code where the exception was thrown, but 1) doesn't necessarily, and 2) if it does, re-runs the code leading up to that point, so if the exception isn't thrown (for whatever reason) the following code can be expected to execute normally (presuming, of course, that the other code is exception safe, so nothing has gotten mucked up in the process).
It's difficult to find good examples of error handling using exceptions (or otherwise, TBH), largely for some of the same reasons for using EH to start with -- the code to handle the exception properly is often (usually?) quite specific to the application at hand. For some small utilities and such, it may just print out an error message and exit. For a server that needs to keep running regardless of what happens, it might write something to the log, then continue executing.
Here "nearest" has nothing to do with location in the source code -- it's based on execution. When code in a try block is executed, the corresponding catch block is set up stack-style. When an exception is thrown, the stack is unwound until it reaches a catch block that can handle the exception that was thrown.
Exceptions are safety nets, but they aren't meant to handle programmer errors (i.e. segfaults)
For example, let's say you're trying to read a file on disk that hasn't been written yet, but you know it will be at some point. Would you want to crash and burn the entire process? Probably not.
If you caught some sort of exception that indicated the file wasn't there yet, you could handle it appropriately by retrying at a later time, or logging some sort of a message.
Note EH = Exception handling
We do EH to make sure that we do not get run time abnormal behavior of program, which can be due to some unexpected input/data at any point of execution or data corruption in processing. It depends on developer how he handles exception(s) i.e show any error message or correct the data and continue.
for example
class PlayGame{
private:
/* variable */
public:
bool inputUserName() throw(){
**** if user do not enter name throw exception
}
void play(){
********
}
void end(){
****
}
};
void game() throw(){
PlayGame pg;
pg.inputUserName();
pg.play();
pg.end();
}
void main(){
/* one way of work */
try{
game()
}catch (exception& e){
cout<<"Error occour.. user name missing..\n";
}
/* second way can be */
try{
game();
}catch (exception& e){
cout<<"Please enter name first...\n";
game();
}
}
This is good example of understanding EH in c++
Maybe the concept of "strong exception safety" provides somewhat an answer to both of your questions. A function which is strongly exception safe will either complete regularily or, if throwing, leave the state of the program as it was before it was called.
Disregarding for the moment if that can be achieved, let's assume your code is composed of strongly exception safe functions:
Obviously execution can continue whenever an exception is caught. Just catch it at a point where there is an alternative route for execution. Ultimately just not executing the program at all. Of course you must admit failure to execute as a possibility. However, anything else would be perfection and somewhat unrealistic.
I recommend Herb Sutter's "Exceptional C++" books (see http://www.gotw.ca/publications/xc++s.htm) or his Guru-of-the-Week postings, e.g. http://www.gotw.ca/gotw/059.htm
In general "error recovery" here means rolling back any changes. This usually can only be achieved by doing everything tentatively, eg. on a copy, until success is ensured.
Above that, error recovery is an architectural issue of designing your program with lots of places, where alternative executions routes exist.
I mean, I knew all the language rules about throw, try {} catch {}, but I am not sure if I am using them correctly in the real world. Please see the following example:
We have a large piece of scientific code which did all sorts of image processing things, recently we decided to spruce it up and make it more robust. One of the routines which is frequently used is void rotate_in_place(float* image, image_size sz);
To make it more robust, we add some sanity check at the beginning of the code:
void rotate_in_place(float* image, image_size sz) {
// rotate_in_place does not support non-square image;
if (sz.nx != sz.ny) throw NonSquareImageError;
// rotate_in_place does not support image too small or too large
if (sz.nx <= 2 || sz.nx > 1024) throw WrongImageSizeError;
// Real rode here
.....
}
Now the problem is that rotate_in_place() is used in over 1000 places, shall I wrap each call of rotate_in_place() with try{} catch {}, this looks to me will make code incredibly bloated. Another possibility is do not wrap any try{} catch{} and let the program exit, but how is this different from just using
if (sz.nx != sz.ny) {
cerr << "Error: non-squared image error!\n";
exit(0);
}
In short, I am not so sure about the real benefit of using throw, try, catch, any good suggestions?
Every site that handles the error needs try-catch block. It all depends on your design, but I doubt you need to handle the error in every rotate_in_place call-site, you probably get away from propagating upwards most of the time.
Printing the error and using exit is bad for three reasons:
You can't handle the error. exit is not handling (unless it's done when the error is absolutely critical, but your function cannot know that — caller might have a way to recover).
You're extending responsibilities of the function with writing to a hard-coded stream, which might not even be available (this is rotate_in_place, not rotate_in_place_and_print_errors_and_kill_the_program_if_something_is_wrong) — this hurts reusability.
You lose all debugging information with this approach (you can generate stack traces from unhandled exceptions, you can't do anything with a function that bails out every time — unhandled exception is a bug, but it's a bug you can follow to the source).
The general rule for exceptions is, "Does the immediate call site care about what's going on here?" If the call site does care, then returning a status code probably makes sense. Otherwise, throwing makes more sense.
Consider it this way -- sure, your rotate in place method has a couple of invalid argument types, in which case you should probably throw std::invalid_argument. It's unlikely that a caller of rotate_in_place wants to deal with or knows how to deal with the case that an image was not square, for example, and therefore that's probably better expressed as an exception.
Another possibility is do not wrap any try{} catch{} and let the
program exit, but how is this different from just using
if (sz.nx != sz.ny) {
cerr << "Error: non-squared image error!\n";
exit(0);
}
It's different because if someone later wants to take your function and put it in, say, a GUI application, they don't have to terminate the program based on the error. They can turn that exception into something pretty for the user or something like that.
It also has benefits for you right now -- namely that you don't have to pull <iostream> into that translation unit simply to do error writing.
I usually use a pattern something like this:
int realEntryPoint()
{
//Program goes here
}
int main()
{
//Allow the debugger to get the exception if this is a debug binary
#ifdef NDEBUG
try
#endif
{
return realEntryPoint();
}
#ifdef NDEBUG
catch (std::exception& ex)
{
std::cerr << "An exception was thrown: " << ex.what() << std::endl;
}
#endif
}
Now the problem is that rotate_in_place() is used in over 1000 places, shall I wrap each call of rotate_in_place() with try{} catch {}, this looks to me will make code incredibly bloated.
It will, and it beats the purpose of using exceptions in the first place.
Another possibility is do not wrap any try{} catch{} and let the program exit, but how is this different from just using [...]
That you can always change the location of exception handling later on. If at some point you find a better place to sensibly handle the error (perhaps recovering from it), then that's the point where you put the catch. Sometimes that's in the very function where you throw the exception; sometimes it's way up in the call chain.
Do put a catch-all in main, just in case. Deriving exceptions from standard ones such as std::runtime_error makes doing this a lot easier.
The point in using exception handling holds in following simple rules:
As soon as anything bad can happen due to bad user input (internal logic should be handled via assertions/logging), throw an exception. Throw as soon as possible, and as much as possible: C++ exceptions are usually pretty cheap compared to say, .Net ones.
Let an exception propagate if you can't handle the error. This means pretty much always.
The thing to remember is: The exception should bubble up to the point where it can be handled. This can mean a dialog box with some formatting of the error, or this can imply that some unimportant piece of logic won't be executed after all, etc.
Using exceptions allows the caller to decide how to handle an error. If you called exit directly within the function, then the program would exit without the caller being able to decide how to handle the error. Also, with exit, stack objects would not be unwound. :-(
What you can do is to make rotate_in_place return a boolean if the function call was succesfull. And return the rotated image via a function parameter.
bool rotate_in_place(float* image, image_size sz, float** rotated_image) {
// rotate_in_place does not support non-square image;
if (sz.nx != sz.ny) return false;
// rotate_in_place does not support image too small or too large
if (sz.nx <= 2 || sz.nx > 1024) return false;
// Real rode here
.....
return true;
}
It depends.
Exceptions are generally meant to be caught/handled. In your case, is it possible to handle the exception (for instance, the user provides a non-square image, so you ask them to try again). However if there is nothing you can do about it, then cerr is the way to go.
Well, I agree that really using Exceptions results in bloated code. That is the main reason for me not liking them.
Anyway, as to your example: The key difference between throwing exceptions and just using exit() is that, since the handling of the exception happens (or is supposed to happen) outside of the program fragment that generated the error/exception, you do not specify how the user of a function/class has to handle the error. By using exceptions you allow different treatments like aborting the program, reporting errors or even recovering from certain errors.
TLDNR: If you use exceptions, the exception-generating part of the code does not need to specify how the exceptional case is treated. That happens in the outside program and can be changed depending on how the code is being used.
I've run into a situation with some code I inherited... honestly, I believe the code is written correctly, but this error still seems to manifest.
I'll quickly note that the code is cross-compiled from linux to LynxOS, I'm not sure if that can have anything to do with the error.
Basically, in one specific case:
try {
std::vector<ClassA> x = SomeGeneratingFunction();
//We get to here fine. X may be empty/unpopulated though.
if (x.size() < 1)
{
throw(MyException("It crashed."));
}
}
catch (MyException e)
{
//Handle it.
}
catch (...)
{
//Handle it.
}
We throw given the vector is unpopulated, but for some reason the throw bypasses the catch clauses - both of them. It only seems to happen here - though we woudln't usually do it form an if statement scope, but that should be completely irrelevant since its still in the try scope.
PS: The code below is actually the contents of a function, and exceptions come out of the function when called even though they should all be handled by the catch blocks.
Any ideas how this is possible? And yes, this isn't the real code/exception classes, but the exception class is the simple example you'd google of overloading std::exception, and the SomeGeneratingFunction() does return a good vector, even if it is empty. I cannot provide the real code, but this is exceedingly close barring any little typos I may have made writitng it off the top of my head.
Since the catch (...) clause didn't catch the exception, my answer does not solve the OP's problem. But for others that found this question on SO, maybe my answer is useful, because it explains why the first catch failed.
I had a similar issue where my catch(const std::exception& ex) was just not working. It turned out to be a dumb problem in that I was switching between C# and C++ exceptions, and in C# you need to specify new when you throw your exception, while in C++ you normally don't (but you can, but in this case you are throwing a pointer and not a reference). I was accidentally doing
throw new std::runtime_error("foo");
so
catch(std::exception* ex)
would have caught it but
catch(std::exception& ex)
doesn't. Of course, the solution is just remove the new statement, as that is not the traditional design pattern in C++.
Since you have a spare set of parentheses around the exception object in the throw statement, it looks like a function call. Is there any possibility that you've defined a function called throw? The parameter to the exception constructor keeps this from being a victim of the Most Vexing Parse, but that's a possibility if your actual code differs from your example.
catch (MyException e)
should read:
catch (const MyException &e)
I'm not sure why your throw looks like a function either, kind of bizarre.
Edit:
I've had problems with catches based on something similar, though I agree that it isn't sufficient in this toy case.
The compiler seems off to me, is Try defined as something funny? If it were empty it could make sense if your compiler ignored catch statements with no try.
If you have a function MyException in a smaller scope (possibly even by accident, Most Vexing Parse) then throw MyException("It crashed") will call that function and throw the return value.
Let me slash the problem... Don't use exceptions in C++ unless you want to crash definitely the program. I know exceptions may be quite useful, but they have very poor performances because it raises up an hardware exception which is caught by the operating system kernel. Using return values and error codes can be 500 times faster than throwing and catching exceptions.
I would just rewrite it without using try/catch. Doesn't seem appropriate to use try/catch here anyway. For all you know, exceptions may not work on your target platform.
Each time I have seen the catch all statement:
try
{
// some code
}
catch (...)
{
}
it has always been an abuse.
The arguments against using cache all clauses are obvious. It will catch anything including OS generated exceptions such as access violations.
Since the exception handler can't know what it's dealing with, in most cases the exceptions will manifest as obscure log messages or some incoherent message box.
So catch(...) seems inherently evil.
But it is still implemented in C++ and other languages (Java, C#) implements similar mechanisms. So is there some cases when its usage is justified?
(1) It's not true that the statement will catch OS exceptions. Your use of the term "Access Violation" betrays a Windows background; it was true for older MSVC++ versions.
(2) Regardsless, the catch-all behavior is useful for threads with specific purposes. Catching the failure allows the thread to report it failed. Without it, the other parts of the program need to deal with the possibility of a thread just disappearing. It also allows you to log which thread failed, and the arguments used to start the thread.
The case where it's justified in general is when you log the exception (or do something similar) or do some cleanup, and then immediately rethrow.
In C++ in particular, logging in a catch(...) block is pretty pointless since you don't have any way to obtain the exception, and cleanup is pointless because you should be using RAII for that. Using it in destructors seems to be about the only legitimate case.
the arguments against using cache all clauses are obvious , it will catch anything including OS generated exceptions such as access violation. since the exception handler can't know what its dealing with, in most cases the exceptions will manifest as obscure log message or some incoherent message box.
And if those same exceptions aren't caught you get... an incoherent message box.
catch(...) lets me at least present my own message box (and invoke custom logging, save a crash dump, etc.).
I think there are also reasonable uses of catch(...) in destructors. Destructors can't throw--well, I mean, they can throw, but if a destructor throws during stack unwinding due to an in-progress exception the program terminates, so they should not ever allow exceptions to escape. It is in general better to allow the first exception to continue to be unwound than to terminate the program.
Another situation is in a worker thread that can run arbitrary functions; generally you don't want an unceremonious crash if the task throws an exception. A catch(...) in the worker thread provides the opportunity for semi-orderly clean-up and shutdown.
In addition to what other posters have already said, I'd like to mention one nice point from the C++ Standard:
If no matching handler is found in a
program, the function std::terminate()
is called; whether or not the stack is
unwound before this call to
std::terminate() is
implementation-defined.
(15.3/9)
This means that main() and every thread function must be wrapped in a catch-all handler; otherwise, one can't even be sure that destructors for automatic objects will be called if an uncaught exception is thrown.
try {...} catch (...) is needed around body of callback function which is called from code
that doesn't understand C++ exceptions (usually C library).
Otherwise, if some C++ library you use throws an exception that doesn't derive from
std::exception, it will probably cause calling code to crash or corrupt its internal state.
Instead you should catch this exception and either finish program immediately or
return some error code (meaning "we are doomed and I don't know why", but it's still better
then letting C++ exception to pass through).
Around thread procedure. Mostly because of the same reason as 1.
And because otherwise thread failure would pass unnoticed.
catch(...) has been useful for me in two circumstances, both of which are unjustified (I can't even remember the second)
The first is my overall application safety. While throwing exceptions that don't derive from std::exception is a No-No, I have one just in case in my main() function:
int execute(void); // real program lies here
int main(void)
{
try
{
return execute();
}
catch(const std::exception& e)
{
// or similar
std::cerr << "Unhandled exception: " << e.what() << std::endl;
return EXIT_FAILURE;
}
catch(...)
{
std::cerr << "Unknown exception!" << std::endl;
return EXIT_FAILURE;
}
}
Now, it's only there "just in case", and it's not really justified. There should be no reason to ever enter that catch clause, as that would mean somebody has done a Bad Thing. Observe how useless the statement really is; "Something bad happened, no clue what!" It's only a step above just crashing in the first place.
The second use might be in destructors or some other function that needs to do manual management before letting the exception propagate. That's not really a justification either, as things should clean themselves up safely with RAII. But I may have used it once or twice for some reason I can't recall, and I can't see a reason to ever do so again.
catch (...) allows you to write code in which you can legitimately claim a guarantee that your code will not crash even when you are not in long term complete control of the submodules your code depends on. Your claim is tantamount to claiming that this semantic cannot be used except as a means of abuse. Maybe so, but military specifications may differ from you on this issue.
catch(...) is necessary in the absence of the finally clause as found in other languages:
try {
...
} catch(...) {
cleanup...
throw;
}
The alternative - making stack objects to 'own' everything - is often much more code and less readable and maintainable. The platform API is often C, and does not come with it conveniently bundled.
It is also useful around plugin code that you do not control or simply do not trust from a stability perspective. It won't stop them crashing, but it might keep things a little saner.
Finally, there are times when you really do not care about the outcome of something.