I am trying to debug my application by using exception catch-rethrows. My exception handling code is longer than some of the blocks I am debugging, and it's all copy-pasted.
Is there a better way to repeatedly express the below code? I suspect macros are the way to go here, but I usually avoid macros like the plague.
try {
// Code here...
}
catch (std::exception & e)
{
ErrorMsgLog::Log("Error", "std exception caught in " __func__ " " __FILE__ " " __LINE__, e.what());
throw e;
}
catch (Exception & e)
{
ErrorMsgLog::Log("Error", "Builder exception caught in " __func__ " " __FILE__ " " __LINE__, e.Message);
throw e;
}
catch (...)
{
ErrorMsgLog::Log("Error", "Unknown exception caught in " __func__ " " __FILE__ " " __LINE__);
throw std::runtime_error ("Unknown Exception in " __func__ " " __FILE__ " " __LINE__);
}
The best way to implement this is probably using macros. The macro definition is a little bit ugly, but calling the macro will be pretty easy, and you will not need to re-organize your code. Here is a sample that shows how you could implement it:
#define RUN_SAFE(code) try {\
code\
}\
catch (std::exception & e)\
{\
ErrorMsgLog::Log("Error");\
throw e;\
}\
catch (Exception & e)\
{\
ErrorMsgLog::Log("Error");\
throw e;\
}\
catch (...)\
{\
ErrorMsgLog::Log("Error");\
throw std::exception();\
}\
int main(){
RUN_SAFE(
cout << "Hello World\n";
)
}
If you are really adamant about not using macros, you could use the approach suggested by #juanchopanza and use a higher-order function for the check that takes the code as a parameter. This approach will probably require you to refactor your code a bit though. Here is how you could implement it:
void helloWorld(){
cout << "Hello World\n";
}
void runSafe(void (*func)()){
try {
func();
}
catch (std::exception & e)
{
ErrorMsgLog::Log("Error");
throw e;
}
catch (Exception & e)
{
ErrorMsgLog::Log("Error");
throw e;
}
catch (...)
{
ErrorMsgLog::Log("Error");
throw std::exception();
}
}
int main(){
runSafe(helloWorld);
}
Related
I do a simple throw "TEST THROW" and it isn't caught in my catch (std::exception& e). Is it because I'm catching an std::exception& e? I mean, are only exception classes derived from std::exception caught? If not, am I doing something wrong or is it normal? By the way, none of the two catch blocks caught the throw exception.
int main()
{
try
{
throw "TEST THROW"; // TEST
Core core;
core.Init();
core.Load();
while (!core.requestCloseWindow)
{
core.HandleInput();
core.Update();
core.Draw();
}
core.Unload();
core.window->close();
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
try
{
time_t rawTime;
struct tm* timeInfo;
char timeBuffer [80];
time(&rawTime);
timeInfo = localtime(&rawTime);
strftime(timeBuffer, 80, "%F %T", timeInfo);
puts(timeBuffer);
std::ofstream ofs; // Pas besoin de close, car le destructeur le fait.
ofs.exceptions(std::ofstream::failbit | std::ofstream::badbit);
ofs.open("log.txt", std::ofstream::out | std::ofstream::app);
ofs << e.what() << std::endl;
}
catch (std::exception& e)
{
std::cerr << "An error occured while writing to a log file!" << std::endl;
}
}
return 0;
}
Another reason people may hit this issue, especially if they've been writing Java recently, is that they may be throwing a pointer to the exception.
/* WARNING WARNING THIS CODE IS WRONG DO NOT COPY */
try {
throw new std::runtime_error("catch me");
} catch (std::runtime_error &err) {
std::cerr << "exception caught and ignored: " << err.what() << std::end;
}
/* WARNING WARNING THIS CODE IS WRONG DO NOT COPY */
will not catch the std::runtime_error* you threw. It'll probably die with a call to std::terminate for the uncaught exception.
Don't allocate the exception with new, just throw the constructor by-value, e.g.
try {
/* note: no 'new' here */
throw std::runtime_error("catch me");
} catch (std::runtime_error &err) {
std::cerr << "exception caught and ignored: " << err.what() << std::end;
}
You're throwing a const char*. std::exception only catches std::exception and all derived classes of it. So in order to catch your throw, you should throw std::runtime_error("TEST THROW") instead. Or std::logic_error("TEST THROW"); whatever fits better. The derived classes of std::exception are listed here.
You can add a
catch (...)
block to get it.
This also may happen when you throw an exception of a an inherted type but the inhertence is private
Since this is not a MCVE (what is Core?), I can't address explicitly the problem, but you are surely missing to
#include <exception>
Actually, GCC compiles even without the inclusion, but exception won't be caught and you will end up with
terminate called after throwing an instance of 'std::exception'
what(): std::exception
./{program}: {PID} Aborted (core dumped)
Problem : I am using both std::exception and std::bad_alloc to catch exception. Something is wrong with the order of the try catch that I am using. I attached sample code for reference.
Expected : If my error is bad_alloc then the bad_alloc exception is thrown.
Observed : My error is bad_alloc, but exception is thrown.
Sample Code :
#include "stdafx.h"
#include <iostream>
#include <exception>
using namespace std;
void goesWrong()
{
bool error1Detected = true;
bool error2Detected = false;
if (error1Detected)
{
throw bad_alloc();
}
if (error2Detected)
{
throw exception();
}
}
int main()
{
try
{
goesWrong();
}
catch (exception &e)
{
cout << "Catching exception: " << e.what() << endl;
}
catch (bad_alloc &e)
{
cout << "Catching bad_alloc: " << e.what() << endl;
}
return 0;
}
You have to put your exceptions in reverse order, regarding their inheritance relationship. std::exception is the parent class of std::bad_alloc, that is why it is found before in the catch list. So you have to transform your code to be:
try {
goesWrong();
}
catch (bad_alloc &e)
{
cout << "Catching bad_alloc: " << e.what() << endl;
}
catch (exception &e)
{
cout << "Catching exception: " << e.what() << endl;
}
You're not limited to catch objects: you can throw integers, chars... whatever. In that case, catch(...) is the only secure way to catch them all.
That said, using objects from the standard class library is the advised way to do it. And in this case, since std::exception is the base class for all (standard) exceptions, it will catch all possible exceptions thrown.
You can create your own exception classes deriving them from std::exception, or from std::runtime_error, for example, my personal choice.
Hope this helps.
In C++, the order in which exception handlers are listed is taken into account when matching handlers to exceptions. The first handler which can handle the exception will be called, even if there is a better match further down the list. This is different from Java or C#, where only the best match will be called (and the compiler forces you to put it at the top of the list).
As the exception is passed by reference, polymorphism applies; this means that a subclass can be passed to a handler that expects its parent class. Since std::bad_alloc is a subclass of std::exception, it will be handled by the first catch block.
To get the behaviour you expected, put the catch blocks the other way round:
catch (bad_alloc &e)
{
cout << "Catching bad_alloc: " << e.what() << endl;
}
catch (exception &e)
{
cout << "Catching exception: " << e.what() << endl;
}
This way round, std::bad_alloc will match the first handler, while std::exception and all its other subclasses will match the second.
I am writing a command-line application in C++. If an unhandled exception occurs, I don't want the app to crash badly, but to clean up as well as possible and print an error message.
How should I catch exceptions at the top-level in order to avoid the program crashing? Should I catch std::exception, ... or something else?
The quality of the cleaning you can do is a function of the exception being thrown.
For example, an exception that you raise yourself (perhaps derived from std::exception; let's call it fooexception) could well be handled quite elegantly.
So really you want a catch site on these lines
try {
/*whatever*/
} catch (fooexception& fe){
/*ToDo - handle my exception*/
} catch (std::exception& e){
/*ToDo - handle this generically*/
} catch (...){
/*Hum. That's bad. Let's do my best*/
}
Extend this at your leisure. Just remember that in a sense, multiple catch blocks behave like if else blocks: always order with the specific exceptions first.
Well, you could catch both:
int main() {
try {
// do stuff
}
catch(const std::exception& e) {
std::cout << "Caught exception: " << e.what() << std::endl;
}
catch(...) {
std::cout << "Caught unknown exception." << std::endl;
}
}
You should catch both, and possibly more. If you use a more specific exception type somewhere in the call stack, try to catch that as well.
Consider the code:
try
{
process();
}
catch (const SpecificException& ex)
{
std::cerr << "SpecificException occured: " << ex.what() << std::endl;
}
catch (const std::runtime_error& ex)
{
std::cerr << "std::runtime_error occured: " << ex.what() << std::endl;
}
catch (...)
{
std::cerr << "Unknown error occured!" << std::endl; // should never happen hopefully
}
And remember to always sort by specificness of exceptions - the more specialized/derived first, as the runtime will stop at the first catch block able to process the exception (i.e. first catch block with exception type matching or being a base of).
I'm writting an QT-application for ARM-processor. I use gcc-linaro-arm-linux-gnueabihf compiller.
I try to caught std::exception
try
{
----CODE HERE----
}
catch(QException e)
{
qCritical() << e.what();
}
catch(std::exception e)
{
qCritical() << e.what();
}
As output I have:
----- Dev started -----
std::exception
----- Dev finished -----
There is no detailed information about an exception.
Ho can I see what kind of std::excpetpion occured?
The another problem, that it's qt application. Makefile is generated by qmake. I can't directly pass options to gcc compiller.
The problem is that you're slicing the exception object—you're catching it by value, so any subclass information is lost. Catch it by const & instead to keep its type & data alive:
catch(const std::exception &e)
{
qCritical() << e.what();
}
Additionally, if you want special handling for more specific types (classes derived from std::exception), you can add it:
catch (const std::invalid_argument &e)
{
qCritical() << "Invalid argument: " << e.what();
}
catch (const std::domain_error &e)
{
qCritical() << "Domain error: " << e.what();
}
catch (const std::excetion &e)
{
qCritical() << "Other exception: " << e.what();
}
Note that the order of catch clauses is important: they are processed sequentially, and the first one matching is used. So derived classes have to be listed before the base class.
I'm not sure I have correctly understood your problem, but straightly answering your question is easy:
try
{
----CODE HERE----
}
catch(const QException& e)
{
qCritical() << "QException exception\n" << e.what();
}
catch(const std::exception& e)
{
qCritical() << "standard library exception\n" << e.what();
}
Don't forget that if another type of exception is thrown, you can always catch it with this:
catch(...)
{
qCritical() << "bad bad things happened, unknown exception!\n";
}
I would like to add information on what the program was about to do to my
exception handling. The old code had one big try-block around everything:
try {
read_cfg(); // a sub call might throw runtime_error
operation1();
operation2();
}
catch (std::exception& e) {
std::cerr
<< "Error: " << e.what() << ", "
// FIXME: also show what we were trying to do
// FIXME: and what a user could try
<< "\n";
}
Example error message:
Error: file "foo.cfg" not found, while reading configuration.
Please make sure the file exists.
I converted the try-block into three blocks, but this feels odd:
try {
read_cfg(); // a sub call might throw runtime_error
}
catch (std::exception& e) {
std::cerr
<< "Error: " << e.what() << ", "
<< "while reading configuration."
<< "\n";
}
try {
operation1();
}
catch (std::exception& e) {
std::cerr
<< "Error: " << e.what() << ", "
<< "while performing operation 1."
<< "\n";
}
try {
operation2();
}
catch (std::exception& e) {
std::cerr
<< "Error: " << e.what() << ", "
<< "while performing operation 2."
<< "\n";
}
I also tried to introduce one exception class per call (read_cfg_exception,
operation1_exception, operation2_exception). Since in read_cfg() the call to
open might throw, I catch its exception and convert it to a
read_cfg_exception, thereby saving the additional information, that something
whent wrong "while reading configuration". Yet this does not feel right either:
class read_cfg_exception;
void open(std::string name); // might throw std::runtime_error
void read_cfg()
{
try {
open("foo.cfg");
}
catch (std::runtime_error& e) {
throw read_cfg_exception(e.what() + "while reading configuration");
}
}
Therefor I have the question: What is a good pattern to show the additional
information of what the program was doing while the error occured.
take a look at POCO (c++ library) throwing system, that should answer all your questions, you'll learn a lot from that and many good style rules too. The answare to your question will be really long unfortunately (at least I don't know how to make it short).
Anyway don't implement something that makes your code not readable, in your example code is not readable and then not maintainable wich is not wanted.