What are the common usage of exceptions at catch site? - c++

My understanding about exception handling is very limited. While I find it is easy to throw an exception (or I can pack it using expected<T> for later consumption), I have very little idea about what to do with an exception.
Presently my knowledge is limited to
clean my own resources and rethrow the exception to be handled at appropriate location. e.g.
ptr p = alloc.allocate(n);
try
{
uninitialized_copy(first,last,p);//atomic granularity, all or none
}
catch(...)
{
alloc.deallocate(p,n);
throw;
}
But I guess, this can be equivalently transformed in a RAII pattern as
alloc_guard<ptr> p{alloc.allocate(n)};
uninitialized_copy(first,last,p.get());
p.commit();
catch the exception at a top level, compose & print a nice message and exit.e.g.
int main(int argc,char** argv)
{
try
{
app_t the_app(argc,argv);
the_app.run();
}
catch(std::runtime_error& e)
{
//instead of what, I can also compose the mesage here based on locale.
std::cout<<e.what()<<std::endl;
}
}
So, all I do is in a top level function such as main catch the exception and print an appropriate message and close.
While implementing a library with a nice set of API using various external libraries as back end for implementation, I realized that third party library exceptions are part of my API specification, as they cross my library boundary and land in user code!
So, my library API leaked all exceptions from external libraries (and each one having their own exception hierarchy) that I was using to the user code.
This leads to my question, what all can be done when I catch any exception ?
More specifically,
Can I translate the caught exception from external library to my own exception and throw that in a generic way (say the mapping between third party library exception hierarchy and my exception API is provided as a mpl::map) ?
Can I do something more useful than printing a message/call stack, say resume the function at the throw site with different input parameter (say when I get that a file_not_found or disk_error, re-run the function with a different file)?
Any other pattern which is valuable to know?
Thanks

Additional to what nogard said I want to add the following:
Exceptions should be used for exceptional things. Things that should not happen.
If you encounter an exception, log it at least somewhere. This might help you finding a bug.
Try to resolve the error at the point where you caught the exception.
If this is not possible, try to stay in a consistent state where the application can continue.
If this is not possible - think about gracefully terminating.
Notify the user that something out of the ordinary happened.
Final advice - keep your error handling consistent. This includes translating exceptions from third party libraries to your exception hierarchy.
Answers to comments:
2) The exception should contain information about what went wrong. This could be just the type or some additional information. Logging these at the customer allows you to get more information on what actually went wrong beyond to what the customer tells you. Perhaps he misused your application, found another use case or you simply have a bug (e.g. a not initialized variable). But with this extra information you have a location where something went wrong and some information on what went wrong. This helps you to deduce the source of the error and thus find the bug.
3) this actually depends on the error that is occurring. E.g. you try to access a configuration file that is not there --> you create a new one with default values. The client tries to open a database for write access, but it is write protected. You decline opening, return to a valid state and tell the client that the db is write protected. You run out of memory and can't continue? Log this (beware - you have no spare memory so your logging should already have reserved some memory upfront for this use case) and gracefully shut down the application. Perhaps, if possible, notify the client.
Regarding code from other libraries: there's no other way then checking each function call to another library for the exceptions it might return and catching them. Once caught, you can transfer the information from that exception into one of yours and throw that exception (or resolve it somehow else)

This is very big subject.
I doubt you can easily translate third party exceptions into your own exceptions, and moreover personally I see no need to implement this behavior. Since 3rd party library is a part of your implementation, which is not exposed to the public API, why would you expose all of its exceptions (even through some mapping)? If one day you stick to another 3rd party library implementing the same stuff - would you like to redesign whole exception hierarchy? I think not. API of your library must not be fragile, so I would propose not to map external exceptions to your own ones.
You can map 3rd party exceptions to your hierarchy following ways:
Don't wrap anything at all. I mean you don't have to throw anything just because 3rd library does so. You can catch that exception and handle it, or return error code, or change the state appropriately. There are many other possibilities rather than rethrowing always.
You don't have to make one-to-one translations for all 3rd party exceptions. If you use library AAA internally, then you can have single AAAException representing many exceptions coming from that library.
Valuable to know: always catch exceptions by const reference:
catch (const exception & ex)
This subject is very big, I hope my answer helps to understand it.
Answers to the comments:
If I do not map third party exceptions to my own API (need not to be one to one), they leak to client code - No, they don't, that's the whole point! You must catch them inside your library and then decide what to do with catched exceptions: throw your own exception, return error code, notify client listener, log error etc...
try {
3rdpatry.call();
} catch (const 3rdpartyException & ex) {
// throw YourException(ex.what());
// listener.notify(some_error)
// return some_code
}
Catching by const reference is not to prevent slicing at all. There is nice discussion here that explains that.

Top-level catch is usually not enough for larger applications. You need to catch exception when you can do something about it, but there are principally only few ways in what to do with an exception:
Recover if you can. - (e.g.: Check for update -> Network connection could not be opened exception -> ignore and don't download the update now.)
Tell the user to choose how to recover. (e.g.: Save file -> File cannot be created exception -> tell user to choose different filename or cancel)
Log and exit. This is the top-level catch-all scenario.

Related

Is it OK to store information regarding an error in an Exception object?

I've been reading about exceptions in C++, the pros and cons, and I've yet to encounter anyone mention the two things I really like about them: They allow me to extend the definition of an error (to something that is more than just an error message as a string), and, they allow me to define a contract between the exception handler and the thrower:
"If I'm going to handle this particular type of error, I'm going to
need this, this and that from you."
I've not seen this mentioned in any of the articles, forums and blog posts, as a pro or a con. And that has made me suspect that my mindset on exceptions and how they should be used may be wrong.
To clarify, here's an example of my usage of exceptions:
A program communicates with a USB device (it sends commands to the device and expects a certain response from it). This USB device can sometimes behave in an unexpected way when responding to a command. In this case, the program will throw an UnexpectedResponseFromDevice exception. The handler for this exception needs more than just an error message in order to do its job. For example, it may need to know of the command that we were sending to the device when the error occurred, and/or the state the device was in. I use the definition of my UnexpectedResponseFromDevice class to explicitly set out what is required to handle the exception. See below for a rough idea.
class UnexpectedResponseFromDevice : public std::exception
{
private:
Command command;
DeviceState deviceState;
std::string msg;
public:
UnexpectedResponseFromDevice(std::string msg, Command command, DeviceState deviceState, ...)
Command getCommand();
DeviceState getDeviceState();
};
This is what I meant by "define a contract between the exception handler and the thrower". In order to throw the exception, these things (in this case a Command, a DeviceState and a message) need to be provided.
Is this an acceptable use case for exceptions? Is it OK for me to store this other information, that is required for the handling of the exception, in the exception object? Is it acceptable but a bad idea? If so, please explain why.
Is this an acceptable use case for exceptions? Is it OK for me to store this other information, that is required for the handling of the exception, in the exception object?
Yes, that's how the exceptions in the standard library do too. One example is std::system_error that derives from std::runtime_error but adds a std::error_code member to carry extra information. One that adds a lot more is std::filesystem::filesystem_error that adds two std::filesystem::path objects.
Is it acceptable but a bad idea? If so, please explain why.
It's only a bad idea if you risk throwing another exception (like a std::bad_alloc) while throwing your exception - or if you use exceptions as something else than exceptions, like choosing between common branches in your program flow. Throwing should preferably be a rare event.
If your have all the info you need in a std::string, or even in something like a std::stack<std::string>>, member variable in the object that is a about to throw you can probably std::move that member object into the exception object to minimize the risk - if you don't need that data anymore in the object that is throwing that is.
I don't know how big your std::string, Command and DeviceState objects are, but you may not want to construct the exception object by taking the parameters by value. Try to make construction noexcept. The getters should also probably return by const&. That's not as critical - but making them so minimizes the risk of an exception in your exception handler.
Yes, a parameter is handed over. By means of it information is made available.
catch(const exception& e) { e....; }

When should you create your own exception type? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I am working on a project where we are restructuring old C code into new C++ where for error handling we are using exceptions.
We are creating different exception types for different modules.
I don't see it is worth but I don't have any valid argument to prove my point. So if we would have written the standard library, you would get to see vector_exception, list_exception and so on.
While thinking about it I stumbled upon this question:
When should you create your own exception type and when should you stick to the exceptions already created in std library?
Also, what could be the problems that we may face in the near future if we go by the above approach?
Create your own exception types when:
you might want to differentiate them when handling. If they're different types, you have the option to write different catch clauses. They should still have a common base so you can have common handling when that is appropriate
you want to add some specific structured data you can actually use in the handler
Having separate list and vector exceptions doesn't seem worthwhile, unless there's something distinctively list-like or vectorish about them. Are you really going to have different catch handling depending on which type of container had an error?
Conversely it could make sense to have separate exception types for things that might be recoverable at runtime, versus things that are rolled-back but could be retried, versus things that are definitely fatal or indicate a bug.
Using the same exception everywhere is easy. Especially when trying to catch that exception. Unfortunately, it opens the door for Pokemon exception handling. It brings the risk of catching exceptions you don't expect.
Using a dedicated exception for all the different modules adds several advantages:
A custom message for each case, making it more useful for reporting
Catch can capture only the intended exceptions, more easily crashes on unexpected cases (yes, thats an advantage over incorrect handling)
On crash, IDE can show the exception type, helping even more with debugging
I think that in addition to the reasons in other answers could be code readability, because a lot of time programmers spend supporting it. Consider two pieces of code (assuming they throw "empty frame" error):
void MyClass::function() noexcept(false) {
// ...
if (errorCondition) {
throw std::exception("Error: empty frame");
}
}
void MyClass::function() noexcept(false) {
// ...
if (errorCondition) {
throw EmptyFrame();
}
}
In the second case I think it is more readable, and the message for the user (which printed with what() function) is hidden inside this custom exception class.
I see two possible reasons.
1) If you want to store in the exception class some custom information about the exception, then you need an exception with extra data members. Often you will inherit from one of the std exception classes.
2) If you want to differentiate between exceptions. For instance suppose you have two distinct invalid argument situations and in your catch block you want to be able to differeentiate between the two. You can create two child classes of std::invalid_argument
The issue I see with each element of the STL firing a distinct memory exception is that some parts of the stl are built on others, so queue would have to catch and translate list exceptions, or clients of queue would have to know to handle list exceptions.
I can see some logic in separating the exceptions from different modules, but I can also see the logic of having a project-wide exception base class. I can also see the logic of having exception type classes.
The unholy alliance would be to build an exception hierarchy:
std::exception
EXProjectBase
EXModuleBase
EXModule1
EXModule2
EXClassBase
EXClassMemory
EXClassBadArg
EXClassDisconnect
EXClassTooSoon
EXClassTooLate
Then insist that every actual fired exception is derived from BOTH a module and a classification. Then, you can catch whatever makes sense to the catcher, such as a disconnection, rather than Having to separately catch HighLevelDisconnect and LowLevelDisconnect.
On the other hand it is also completely fair to suggest that the HighLevel interface should have completely dealt with LowLevel failures, and they should never be seen by the HighLevel API client. This is where catching by module would be a useful last-ditch feature.
I would ask, of the try...catch section, "does this code know how to recover from the error, or not?
Code which uses try...catch is anticipating that an exception could happen. Reasons that you would write try...catch at all instead of letting the exception simply pass through are:
Add some code to make the parent function exception safe. A lot of this should be done quietly with RAII in destructors, but sometimes (e.g. a move operation) need more work to roll-back a partially completed job, it depends on the level of exception safety you want.
Emit or add some debugging information and rethrow the exception.
Try to recover from the error.
For cases 1 and 2 you probably don't need to worry about user exception types, they will look like this
try {
....
} catch (const std::exception & e) {
// print or tidy up or whatever
throw;
} catch (...) {
// print or tidy up or whatever
// also complain that std::exception should have been thrown
throw;
}
This will probably by 99% of real world cases, in my experience.
Sometimes you will want to recover from the error. Maybe the parent function knows that a library will fail in certain conditions which can be fixed dynamically, or there is a strategy for re-attempting a job using different mechanisms.
Sometimes the catch block will be written specifically because the lower-level code has been designed to throw exceptions as part of its normal flow. (I often do this when reading untrusted external data, where many things can predictably go wrong.)
In these, rarer cases, user-defined types make sense.

Try / Catch / Throw / Finally / Rethrow in Coldfusion/Lucee

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.

Why wouldn't you declare main() using a function-try-block?

There are a few SO posts about whether or not declaring main() using function-try-block syntax is valid syntax, and the general consensus seems to be that it's perfectly valid. This left me wondering... is there any reason (performance, style, thread synchronization, multithreading) why one wouldn't use this syntax for main() as a general rule to catch any unhandled exceptions anywhere more gracefully?
Obviously, ideally there won't be unhandled exceptions, but they happen and I think it'd be nice to provide something more informative than the OS-specific default handler. For example, in my case, I'd like to provide a support email address to the user so they can report the crash and have my program submit a log to my cloud-based crash log.
For example, in my case, I'd like to provide a support email address to the user
Well, how are you going to do that in a server with no user-facing interface?
Actually, how are you going to do that even in a process with user-facing components, if you have no way to tell in the catch block what state they're in?
And, for those processes where you can't show the user anything useful (or don't have any concept of a "user" in the first place), what would you do in your catch block that would be better than the default terminate?
As for
... more informative than the OS-specific default handler ...
many OS' default behaviour will be to save a complete snapshot of the process execution state, at the point the un-handled exception is thrown, to a file for debugging. As the developer, I can't think of many default behaviours that would be more informative.
Admittedly I'd prefer something more polished as the end user of a desktop app, but that's a pretty small subset of C++ programs.
You can easily convert
int main() try {
// The real code of main
}
catch (...)
{
}
to
int realMain()
{
// The real code of main
}
int main()
{
try
{
return realMain();
}
catch ( ... )
{
}
}
without losing functionality/behavior.
I am going to guess that whether you use the first version or the second version is a matter of coding practices of a team. From a compiler and run time standpoint, I don't see any semantic difference.
If you happened to have a variable that you want to access in your catch block, you would need the curly braces to provide visibility. But even that could be handled with nested try/catch...
why one wouldn't use this syntax for main() as a general rule to catch
any unhandled exceptions anywhere more gracefully?
compatibility with C.
Sometimes there is no way to handle unhandled exceptions more gracefully.
Obviously, ideally there won't be unhandled exceptions, but they
happen and I think it'd be nice to provide something more informative
than the OS-specific default handler. For example, in my case, I'd
like to provide a support email address to the user so they can report
the crash and have my program submit a log to my cloud-based crash
log.
If unexpected exception happens you can not be sure that it is possible to handle it correctly. What are you going to do if there is a network error exception in your example. And trying to send e-mail causes another exception? There can be other errors when you can not be sure that your data is not corrupted and you can not be sure that your program can run correctly after this error. So if you don't know what error happened it is better to allow your program to crash.
You can implement another "watcher" service that checks if process is running and if it has been crashed it can send e-mail to your users with the logs and core dumps.
If you catch the (otherwise) uncaught object, you won't be able to figure out how the execution reached the throw by inspecting the stack trace, because when exception handler is executed, the stack has already been unwound.
If you let the unexpected exception to be uncaught, you may be able to inspect the stack trace in the terminate handler - this is not guaranteed by the standard, but that's not a big deal since there is no standard way to inspect the stack trace either (in C++). You can either use platform specific API within the program, or an external debugger for the inspection.
So for example in your case, the advantage of not catching the exception would be that you can attach a stack trace to the log entry that you intend to submit.
Also, there are cases where an exception can not be handled by a catch block. For example, when you throw from a destructor that is being executed as a result of throwing an exception. So, to handle these "uncatchable" exceptions, you need a terminate handler anyway, so there is little advantage in duplicating the functionality in the case of uncaught exceptions.
As for the syntax that you use to catch the exception, there is no difference. The case where the function try block is different is a constructor, where it allows catching exceptions thrown by sub object constructors.

In C++, Is it possible to force the user to catch exceptions?

In short, is it possible to get C++ to force the invoker of a method to put a try...catch block?
(To clarify:
I don't necessarily mean the immediate invoker, I mean forcing the fact that it's caught somewhere. Also, I'm talking about forcing at compile time.)
The long:
I've read that it not recommended to use exception specification and that it doesn't work properly anyway (http://4thmouse.com/mystuff/articles/UsingExceptionsEffectively.html)
But the general consensus seems to favor the use of exceptions to return errors over the user of writing methods that return error codes.
So if I'm writing say a library, what's to stop the user from calling my method without putting any try...catch blocks, and then getting his program crashing when my code throws an exception?
(To be clear, I only require the exception to be caught somewhere in the users stack, not necessarily in the immediate calling code, and the compiler to complain if this is not the case.)
No, it is not.
Indeed, there is no mechanism to force the caller of a function (anywhere in the call stack) to handle any kind of error. At least, not via a compilation failure. Return values can be discarded. Even bundling error codes with return values (via expected<T, E>) doesn't issue a compile-time error if the user doesn't actually check to see if the value is available before fetching it.
C++17 may give us the [[nodiscard]] attribute, which allows compilers to issue a warning if a return value (presumably an error code) is discarded by the caller. But a compile-time warning will be as close as you can get.
In short, is it possible to get C++ to force the invoker of a method
to put a try...catch block?
No. This would defeat the whole purpose of exceptions. Exceptions are specifically made for the use case of propagating errors across multiple layers without the intermediate layers being aware of them.
Let's say you have a call hierarchy like A -> B -> C -> D -> E, and an error occurs in E. A can handle the error. B, C and D do not need to be aware of the error at all. This is exactly what exceptions are good for!
If you want to return an error directly to the caller because handling the error is indeed the caller's concern, then an exception is often the wrong design and a return value might be the better choice.
"Enforced" exceptions of a certain form have been tried in Java, but I'd consider it a failed experiment, as it usually results in code like this:
try {
method();
} catch (SomeCheckedException ex) {
// ignore
}
That C++ does not encourage this should be considered a feature.
I've read that it not recommended to use exception specification and
that it doesn't work properly anyway
Exactly. The only exception specification which was ever useful and which worked was throw() to signal that no exception at all is thrown, and that one has been superseded in C++11 by noexcept.
But the general consensus seems to favor the use of exceptions to
return errors over the user of writing methods that return error
codes.
See above. It depends on whether you want an error to propagate or if the caller can and should handle it.
So if I'm writing say a library, what's to stop the user from calling
my method without putting any try...catch blocks, and then getting his
program crashing when my code throws an exception?
A library which requires its user to surround all function calls with try blocks has a bad interface and should be redesigned, accordingly.
Also... you assume that a "program" will use your library. But this assumption will not always be true. The library client may itself be a library. There may be a lot of different library layers between the program and your library. You use exceptions if you do not care which layer handles them.
There's a general consensus? Not that I'm aware of. As for the exceptions, no. The compiler cannot enforce that somebody catches the exception somewhere up the call stack. At compile time, the compiler has no idea who may be calling your function, and your function may throw any arbitrary exception, as may any function that your function calls. The linker might have a chance, but it would have to maintain a lot of extra information dealing with what exceptions a function may throw, as well as what exceptions a function may catch. This gets even uglier when you start to talk about dynamically loaded libraries (DLL/.so) as that would have to get resolved at runtime.