How can we throw an expcetion with a message? - c++

I need to throw an exception and print some helpful message. I tried this:
throw std::exception("message");
throw std::exception(std::string("message"));
untill I found that std::exception had only two constructors:
exception();
exception( const exception& other );
So what is the good way?

You can try to throw it like this:
#include <iostream>
throw std::runtime_error(std::string("Failed: ") + message);
throw std::runtime_error("Error: " + message);
Also you can use the boost::format
throw std::runtime_error(boost::format("There is an exception") % message);

std::exception has an inbuilt virtual called .what() to retrieve things local to the exception in generic catch statements. It's for you to set it.
Otherwise except and catch specifically and consider logging from the catch, which in itself isn't bad practice, but of course if you use the same exception in several places far from ideal if you wanted a centralized message (it's best done that way if you want to log where you caught rather than what).
Wide catches, or worse catch all, have their risks, and as there is no way for a catch all to know the details of your specific exceptions what() is the only guaranteed commonality that I know of.

Related

Should I write catch (...) after catch (exception& e)?

If I know that in the code there is no programmer-defined exception and want to catch only the one thrown by standard libs, is it enough just to write catch (std::exception& e), or I still need to write after it catch (...) ?
int main()
{
try
{//something
}
catch (std::exception& e) { /*something*/}
catch (...) {/*something*/} //unnecessary?
}
So basically it's a question about can I be sure that all throw from std methods and functions are exception derived from std::exception?
My answer: It depends.
What's your purpose in catching the exception? Can you do anything about it? Are you simply logging its existence, or making a friendly report to the user rather than a crash? How big is the codebase? How certain are you there are no exceptions thrown that are not in the standard exception hierarchy?
I've done this sometimes, usually when I hit an uncaught exception and was trying to debug it. I'll include the catch (...) in there just in case somebody stuck a throw 42; or something equally brilliant in there. But generally, I don't really use them in real code.
Yes, cppreference says:
All exceptions generated by the standard library inherit from
std::exception.

How to properly catch std and boost exceptions

Please tell me how to use try/catch properly with boost::exception.
This is one of examples
void Settings::init(const std::string &filename)
{
using boost::property_tree::ptree;
try
{
read_xml(filename, pt);
}
catch(boost::exception const& ex)
{
LOG_FATAL("Can't init settings. %s", /* here is the question */);
}
}
Do I need catch std::exception too?
I can't let my application fail, so I just need to log everything.
UPD:
I also can't understand now to retrive information for logging from exception???
std::exception has a member function called what() that returns a const char* that might explain what happened. If you want to log it (guessing that LOG_FATAL wraps printf somehow) you can do:
catch(std::exception const& ex)
{
LOG_FATAL("Can't init settings. %s", ex.what());
}
For boost::exception though you can use boost::get_error_info to find out more about it.
probably WAY too late in answering... but
<...snip...>
catch (const boost::exception& e)
{
std::string diag = diagnostic_information(e);
// display your error message here, then do whatever you need to, e.g.
LOG_FATAL("Can't init settings. %s", diag);
}
<...snip...>
As with any C++, the following universal rule applies:
Catch all exceptions that can possibly be thrown, and only if you can respond to them meaningfully.
You can catch all other exceptions (...) as well and create a log message or something like that, but then you have to rethrow them (throw;). If there's nothing you can do in your code other than abort some operation, then you don't need to handle the exception. Let it bubble up to a place where it can be used meaningfully.
In your code, you will have to allow at least for memory allocation errors (std::bad_alloc), so you could check for those, if that makes sense. But again, if you don't know what you're catching, there's not much you can do with what you catch.
Saying your "program cannot fail" can only mean so much. Ultimately, if you have an allocation error in a top-level data structure, there's nothing you can do. The best scenario I can imagine is if your main function processes some data in a loop; in that case, you can put a universal try block around the loop, and in case of an exception you just move on to the next round. But I would count that as an instance of being able to "handle an exception meaningfully", so that's just a special case of the above. In general, while you may want to wrap your entire main function in a try block, you'll just have to accept that in the ultimate catch-all case you don't have much of a choice but to abort the program.
That depends on the code that you're running in the try block. If the code in read_xml could throw a std::exception then you would be better to catch std::exception as well. If you're unsure, then it can't really hurt to catch both of them.
You should catch only special exception types if you really want to do something related to that type. Otherwise just use std::exception. If you're code could throw something different, than catch ... instead or after std::exception.
If you want to handle multiple (special) exception types than you need to handle the most explicit first.

How to check that all exceptions thrown have their matching catch clause

In java the compiler complains about uncatched exceptions.
I use exceptions in C++ and I miss that feature.
Is there a tool out there capable of doing it? maybe a compiler option (but I doubt it)
a static analyzer can run over your code and warn you if a function might throw an unhandled exception
for example good old pc-lint
or coverity
There really isn't any way of doing that in C++. But it's easy enough to provide default exception handling at the top level of your program which will catch anything that got missed in the lower levels. Of course, you really don't want to catch most exceptions at this level, but you can at least provide reasonable diagnostic messages.
You just have to catch all exceptions at the top level. Typically this will be enough:
try {
//do stuff
} catch( std::exception& e ) {
// log e.what() here
} catch( YourCustomExceptionHierarchyRoot& e) {
// Perhaps you have smth like MFC::CException in your library
// log e.MethodToShowErrorText() here
} catch( ... ) {
// log "unknown exception" here
}
you will need to do this at the top level of your program (smth like main()).
Also if you implement COM methods you'll have to do the same for each COM-exposed piece of code - throwing exceptions through the COM boundary is not allowed.
Java has checked exceptions, which is different from how C++ goes about it. One way of catching all exceptions is ... syntax, as bellow:
try
{
// code here can throw
}
catch ( const std::exception& stde )
{
// handle expected exception
}
catch ( ... )
{
// handle unexpected exceptions
}
There's also a runtime mechanism to react to unexpected exceptions via set_unexpected(), though its usefulness is debatable.
The preferred approach is to attempt writing exception-safe code.

Can't catch exception!

I'm using swig to wrap a class from a C++ library with python. It works overall, but there is an exception that is thrown from within the library and I can't seem to catch it in the swig interface, so it just crashes the python application!
The class PyMonitor.cc describes the swig interface to the desired class, Monitor.
Monitor's constructor throws an exception if it fails to connect. I'd like to handle this exception in PyMonitor, e.g.:
PyMonitor.cc:
#include "Monitor.h"
// ...
bool PyMonitor::connect() {
try {
_monitor = new Monitor(_host, _calibration);
} catch (...) {
printf("oops!\n");
}
}
// ...
However, the connect() method never catches the exception, I just get a "terminate called after throwing ..." error, and the program aborts.
I don't know too much about swig, but it seems to me that this is all fine C++ and the exception should propagate to the connect() method before killing the program.
Any thoughts?
You have to forward the exceptions to Python if you want to parse them there.
See the SWIG Documentation.
In order to forward exceptions, you only have to add some code in the SWIG interface (.i) file. Basically, this can be anywhere in the .i file.
All types of exceptions should be specified here, and SWIG only catches the listed exception types (in this case std::runtime_error, std::invalid_argument, std::out_of_range), all other exceptions are caught as unknown exceptions (and are thus forwarded correctly!).
// Handle standard exceptions.
// NOTE: needs to be before the %import!
%include "exception.i"
%exception
{
try
{
$action
}
catch (const std::runtime_error& e) {
SWIG_exception(SWIG_RuntimeError, e.what());
}
catch (const std::invalid_argument& e) {
SWIG_exception(SWIG_ValueError, e.what());
}
catch (const std::out_of_range& e) {
SWIG_exception(SWIG_IndexError, e.what());
}
catch (...) {
SWIG_exception(SWIG_RuntimeError, "unknown exception");
}
}
I'm not familiar with swig, or with using C++ and Python together, but if this is under a recent version of Microsoft Visual C++, then the Monitor class is probably throwing a C structured exception, rather than a C++ typed exception. C structured exceptions aren't caught by C++ exception handlers, even the catch(...) one.
If that's the case, you can use the __try/__except keywords (instead of try/catch), or use the _set_se_translator function to translate the C structured exception into a C++ typed exception.
(Older versions of MSVC++ treated C structured exceptions as C++ int types, and are caught by C++ handlers, if I remember correctly.)
If this isn't under Microsoft Visual C++, then I'm not sure how this could be happening.
EDIT: Since you say that this isn't MSVC, perhaps something else is catching the exception (and terminating the program) before your code gets it, or maybe there's something in your catch block that's throwing another exception? Without more detail to work with, those are the only cases I can think of that would cause those symptoms.
It's possible that a function called directly or indirectly by the Monitor constructor is violating its exception specification and doesn't allow std::bad_exception to be thrown. If you haven't replaced the standard function for trapping this, then it would explain the behaviour that you are seeing.
To test this hypothesis you could try defining your own handler:
void my_unexpected()
{
std::cerr << "Bad things have happened!\n";
std::terminate();
}
bool PyMonitor::connect() {
std::set_unexpected( my_unexpected );
try {
_monitor = new Monitor(_host, _calibration);
} catch (...) {
printf("oops!\n");
}
}
If you get the "Bad things have happened!" error message then you have confirmed that this is the case, but unfortunately there may not be a lot that you can do. If you're 'lucky', you may be able to throw an exception from my_unexpected that is allowed by the exception specification of the function that is currently failing, but in any case your unexpected handler is not allowed to terminate normally. It must throw or otherwise terminate.
To fix this you really need to get into the called code and either correct it so that the exception specification is not violated, either by fixing the specification itself or by fixing the code so that it doesn't throw the exception that isn't expected.
Another possibility is that an exception is being thrown during stack unwinding caused by the original exception being thrown. This also would cause termination of the process. In this case, although you can replace the standard terminate function, you have no option but to abort the program. A terminate handler isn't allowed to throw or return, it must terminate the program.

C++ catching all exceptions

Is there a c++ equivalent of Java's
try {
...
}
catch (Throwable t) {
...
}
I am trying to debug Java/jni code that calls native windows functions and the virtual machine keeps crashing. The native code appears fine in unit testing and only seems to crash when called through jni. A generic exception catching mechanism would prove extremely useful.
try{
// ...
} catch (...) {
// ...
}
will catch all C++ exceptions, but it should be considered bad design. You can use c++11's new current_exception mechanism, but if you don't have the ability to use c++11 (legacy code systems requiring a rewrite), then you have no named exception pointer to use to get a message or name. You may want to add separate catch clauses for the various exceptions you can catch, and only catch everything at the bottom to record an unexpected exception. E.g.:
try{
// ...
} catch (const std::exception& ex) {
// ...
} catch (const std::string& ex) {
// ...
} catch (...) {
// ...
}
Someone should add that one cannot catch "crashes" in C++ code. Those don't throw exceptions, but do anything they like. When you see a program crashing because of say a null-pointer dereference, it's doing undefined behavior. There is no std::null_pointer_exception. Trying to catch exceptions won't help there.
Just for the case someone is reading this thread and thinks he can get the cause of the program crashes. A Debugger like gdb should be used instead.
This is how you can reverse-engineer the exception type from within catch(...) should you need to (may be useful when catching unknown from a third party library) with GCC:
#include <iostream>
#include <exception>
#include <typeinfo>
#include <stdexcept>
int main()
{
try {
throw ...; // throw something
}
catch(...)
{
std::exception_ptr p = std::current_exception();
std::clog <<(p ? p.__cxa_exception_type()->name() : "null") << std::endl;
}
return 1;
}
and if you can afford using Boost you can make your catch section even simpler (on the outside) and potentially cross-platform
catch (...)
{
std::clog << boost::current_exception_diagnostic_information() << std::endl;
}
try {
// ...
} catch (...) {
// ...
}
Note that the ... inside the catch is a real ellipsis, ie. three dots.
However, because C++ exceptions are not necessarily subclasses of a base Exception class, there isn't any way to actually see the exception variable that is thrown when using this construct.
it is not possible (in C++) to catch all exceptions in a portable manner. This is because some exceptions are not exceptions in a C++ context. This includes things like division by zero errors and others. It is possible to hack about and thus get the ability to throw exceptions when these errors happen, but it's not easy to do and certainly not easy to get right in a portable manner.
If you want to catch all STL exceptions, you can do
try { ... } catch( const std::exception &e) { ... }
Which will allow you do use e.what(), which will return a const char*, which can tell you more about the exception itself. This is the construct that resembles the Java construct, you asked about, the most.
This will not help you if someone is stupid enough to throw an exception that does not inherit from std::exception.
In short, use catch(...). However, note that catch(...) is meant to be used in conjunction with throw; basically:
try{
foo = new Foo;
bar = new Bar;
}
catch(...) // will catch all possible errors thrown.
{
delete foo;
delete bar;
throw; // throw the same error again to be handled somewhere else
}
This is the proper way to use catch(...).
it is possible to do this by writing:
try
{
//.......
}
catch(...) // <<- catch all
{
//.......
}
But there is a very not noticeable risk here: you can not find the exact type of error that has been thrown in the try block, so use this kind of catch when you are sure that no matter what the type of exception is, the program must persist in the way defined in the catch block.
You can use
catch(...)
but that is very dangerous. In his book Debugging Windows, John Robbins tells a war story about a really nasty bug that was masked by a catch(...) command. You're much better off catching specific exceptions. Catch whatever you think your try block might reasonably throw, but let the code throw an exception higher up if something really unexpected happens.
Let me just mention this here: the Java
try
{
...
}
catch (Exception e)
{
...
}
may NOT catch all exceptions! I've actually had this sort of thing happen before, and it's insantiy-provoking; Exception derives from Throwable. So literally, to catch everything, you DON'T want to catch Exceptions; you want to catch Throwable.
I know it sounds nitpicky, but when you've spent several days trying to figure out where the "uncaught exception" came from in code that was surrounded by a try ... catch (Exception e)" block comes from, it sticks with you.
Well, if you would like to catch all exception to create a minidump for example...
Somebody did the work on Windows.
See http://www.codeproject.com/Articles/207464/Exception-Handling-in-Visual-Cplusplus
In the article, he explains how he found out how to catch all kind of exceptions and he provides code that works.
Here is the list you can catch:
SEH exception
terminate
unexpected
pure virtual method call
invalid parameter
new operator fault
SIGABR
SIGFPE
SIGILL
SIGINT
SIGSEGV
SIGTERM
Raised exception
C++ typed exception
And the usage:
CCrashHandler ch;
ch.SetProcessExceptionHandlers(); // do this for one thread
ch.SetThreadExceptionHandlers(); // for each thred
By default, this creates a minidump in the current directory (crashdump.dmp)
Be aware
try{
// ...
} catch (...) {
// ...
}
catches only language-level exceptions, other low-level exceptions/errors like Access Violation and Segmentation Fault wont be caught.
A generic exception catching mechanism
would prove extremely useful.
Doubtful. You already know your code is broken, because it's crashing. Eating exceptions may mask this, but that'll probably just result in even nastier, more subtle bugs.
What you really want is a debugger...
Can you run your JNI-using Java application from a console window (launch it from a java command line) to see if there is any report of what may have been detected before the JVM was crashed. When running directly as a Java window application, you may be missing messages that would appear if you ran from a console window instead.
Secondly, can you stub your JNI DLL implementation to show that methods in your DLL are being entered from JNI, you are returning properly, etc?
Just in case the problem is with an incorrect use of one of the JNI-interface methods from the C++ code, have you verified that some simple JNI examples compile and work with your setup? I'm thinking in particular of using the JNI-interface methods for converting parameters to native C++ formats and turning function results into Java types. It is useful to stub those to make sure that the data conversions are working and you are not going haywire in the COM-like calls into the JNI interface.
There are other things to check, but it is hard to suggest any without knowing more about what your native Java methods are and what the JNI implementation of them is trying to do. It is not clear that catching an exception from the C++ code level is related to your problem. (You can use the JNI interface to rethrow the exception as a Java one, but it is not clear from what you provide that this is going to help.)
For the real problem about being unable to properly debug a program that uses JNI (or the bug does not appear when running it under a debugger):
In this case it often helps to add Java wrappers around your JNI calls (i.e. all native methods are private and your public methods in the class call them) that do some basic sanity checking (check that all "objects" are freed and "objects" are not used after freeing) or synchronization (just synchronize all methods from one DLL to a single object instance). Let the java wrapper methods log the mistake and throw an exception.
This will often help to find the real error (which surprisingly is mostly in the Java code that does not obey the semantics of the called functions causing some nasty double-frees or similar) more easily than trying to debug a massively parallel Java program in a native debugger...
If you know the cause, keep the code in your wrapper methods that avoids it. Better have your wrapper methods throw exceptions than your JNI code crash the VM...
If you are looking for Windows-specific solution then there is structured exception handling:
https://learn.microsoft.com/en-us/cpp/cpp/try-except-statement
The code looks as follows
__try
{
// code here may throw or make access violation
}
__except( EXCEPTION_EXECUTE_HANDLER )
{
// after exception code here, e.g. log the error
}
It will catch not only C++ exceptions but also access violations or other system exceptions.
Well this really depends on the compiler environment.
gcc does not catch these.
Visual Studio and the last Borland that I used did.
So the conclusion about crashes is that it depends on the quality of your development environment.
The C++
specification says that catch(...) must catch any exceptions, but it doesn't in all cases.
At least from what I tried.