Reputation: 312
So I've got a program with two exception. In both cases, I'd like to throw a string that can be caught in the main function and used in an error message. However, from what I know about them
try {
...
} catch(string msg) {
cerr << "..." << msg << "..." << endl;
} catch (string msg2) {
cerr << "..." << msg2 << "..." << endl;
}
isn't allowed. Is there any way I could do the above or something like it? Thanks
Upvotes: 0
Views: 10213
Reputation: 24966
I see two use cases:
1. You want two distinct types of errors.
Add exception classes derived from std::exception
class MyException1 : public std::exception
{
std::string message;
public:
MyException1(std::string const &what_arg) : message(what_arg) {}
MyException1(char const * what_arg) : message(what_arg) {}
const char* what() const { return message.c_str(); }
};
class MyException2 : public std::exception
{
std::string message;
public:
MyException2(std::string const &what_arg) : message(what_arg) {}
MyException2(char const * what_arg) : message(what_arg) {}
const char* what() const { return message.c_str(); }
};
and catch those:
try
{
int a = 5;
// do stuff
if (a == 7)
{
throw MyException1("Error 1 occured in because a == 7.");
}
else if (a == 5)
{
throw MyException1("Error 1 occured because a == 5.");
}
// do more stuff
if (a == 22)
{
throw MyException2("Error 2 occured in because a == 22.");
}
else if (a == 575)
{
throw MyException2("Error 2 occured because a == 575.");
}
}
catch (MyException1 &ex)
{
std::cout << "Exception 1: " << ex.what() << "\n";
}
catch (MyException2 &ex)
{
std::cout << "Exception 2: " << ex.what() << "\n";
}
Note: This is an easy but not the best design for a custom exception since std::string
may throw and your program will be terminated.
2. You want two different error messages:
Use the appropriate type of exception from <stdexcept>
header:
try
{
int a = 5;
// do stuff
if (a == 7)
{
throw std::runtime_error("Error 1 occured because a == 7.");
}
else if (a == 5)
{
throw std::runtime_error("Error 2 occured because a == 5.");
}
}
catch (const std::exception &ex)
{
std::cout << "Exception: " << ex.what() << "\n";
}
Note: The behaviour of case 1 can be emulated in case 2 without own types if the only desired behaviour is different output:
try
{
int a = 5;
// do stuff
if (a == 7)
{
throw std::runtime_error("Exception 1: Error 1 occured in because a == 7.");
}
else if (a == 5)
{
throw std::runtime_error("Exception 1: Error 1 occured because a == 5.");
}
// do more stuff
if (a == 22)
{
throw std::runtime_error("Exception 2: Error 2 occured in because a == 22.");
}
else if (a == 575)
{
throw std::runtime_error("Exception 2: Error 2 occured because a == 575.");
}
}
catch (const std::exception &ex)
{
std::cout << ex.what() << "\n";
}
Upvotes: 6
Reputation: 21576
First: Your compiler is supposed to issue a warning for that, because, the second catch
will never be executed, because they are of exact signatures. Besides, you cannot have a second exception being thrown while the first is active ( exception thrown during stack unwinding that hasn't entered a catch
block yet), else, the runtime will terminate your program.
Secondly: prefer to catch your exceptions by reference
Thirdly: Prefer to have your exception object fall in the inheritance tree of std::exception
.
Lastly: What the hell are you trying to do?
Upvotes: 0
Reputation: 867
Use std::runtime_error it has a constructor that takes a string. So pass it a different value when it is throw.
throw runtime_error( "msg1");
...
throw runtime_error("msg2");
Then when you catch just print the message in the object
...
catch( exception& e ){
cout << e.what() << endl;
}
Upvotes: 2