Catch an pre-defined int exception - c++

I have defined a simple int error code:
#define my_error 20
Somewhere in my code I throw this error:
throw my_error;
Now I want to try and catch this exception thrown:
try
{
...
...
}
catch (my_error)
{
cout << "Error: my error";
}
Unfortunately the compiler doesn't approve this:
syntax error : 'constant'
catch handlers must specify one type
'try' block starting on line '34' has no catch handlers
Is there a way to do this?

20 is not a type, so you can't catch it. What you can do is filter the values in the catch block:
catch (int exception)
{
if ( exception == 20 )
cout << "Error: my error";
}
An even better approach would be to define your own exception:
class MyException : public std::exception
{
}
//...
try
{
throw MyException();
}
catch(MyException& ex)
{
}

If you use C++11, you can use decltype(my_error), just in case you ever change the type of my_error.
try {
// ...
} catch (const decltype(my_error)& e) {
// ...
}
Here is a demo.

Related

C++ nested method try catch (practices)

I'm new to C++ (coming from C) and writing a class B that is a member of another class A.
The member B will throw an exception if the parent tries to access data that does not exist from B's container (I throw an invalid_argument exception). The member B has an object that can be thought of like an STL container, so it will be for this example.
My question is: if I catch the original invalid_parameter exception in A, is it considered good C++ practice to re-throw the same exception (I'd re-throw the original error, but I do some logging in it, so the what() is different), or can I just throw std::exception. My code now has many
try { A.calls_b_exception } catch (std::invalid_argument& ie) {...} catch (std::exception& e) {...}
blocks and I was wondering if I could reduce them to
try { A.calls_b_exception } catch (std::exception& e) {...}
and still be following good C++ paradigms.
Example code that is similar to my situation:
class B
{
std::vector<int> stuff;
int get_value(int index)
{
if (index >= stuff.size()) {
stringstream err;
err << "--> invalid index " << index << " for stuff";
throw std::invalid_argument(err.str());
}
}
}
class A
{
B b;
// Assume there are methods to add a bunch of stuff to B
int get_value(int index)
{
try {
b.get_value();
} catch (std::invalid_argument& ie) {
stringstream err;
err << ie.what() << "\n\t--> A::get_value(" << index << ")";
// should I throw the same exception here or is this considered good C++ etiquette?
throw std::exception(err.str());
} catch (std::exception& e) {
throw; // something I was not anticipating handling happened
}
}
}
int main
{
A a;
// Assume more stuff to add to A
try {
a.get_value(-1);
}
catch (std::exception& e) {
stringstream err;
err << "--> invalid index " << index << " for main";
throw std::exception(err.str());exception here?
}
}
You cannot instantiate std::exception(std::string), so my initial approach will not work.
Thanks to those of you who took time to read through my question and help me out.

How to catch all custom exceptions in a single catch statement with Apache Thrift?

I have many different exceptions defined in exception.thrift:
exception InvalidArgumentsError {
1: string parameter
}
/**
* Server has an problem while executing a function.
* Execution aborted.
*/
exception ServerInternalError {
1: string parameter
}
/**
* Server answer is empty.
*/
exception NoDataError {
1: string parameter
}
This is how i catch them in my C++ code:
catch (InvalidArgumentsError & ex) {
std::cout << ex.parameter;
}
catch (ServerInternalError & ex) {
std::cout << ex.parameter;
}
catch (NoDataError & ex) {
std::cout << ex.parameter;
}
catch (apache::thrift::TException& ex) {
std::cout << "TException:\n" << ex.what();
} catch (const std::exception& ex) {
std::cout << ex.what();
return;
}
I want to write something like this and catch all my exceptions:
catch (SomeBasicException& ex) {
std::cout << ex.what();
}
catch (const std::exception& ex) {
std::cout << ex.what();
}
If I just catch TException and call what() I just get 'Default TException' message because derived classed do not override virtual what() method.
Generated code by thrift compiler:
class InvalidArgumentsError : public ::apache::thrift::TException {
public:
static const char* ascii_fingerprint; //..
static const uint8_t binary_fingerprint[16]; //..
InvalidArgumentsError() : parameter() {
}
virtual ~InvalidArgumentsError() throw() {}
std::string parameter;
_InvalidArgumentsError__isset __isset;
void __set_parameter(const std::string& val) {
parameter = val;
}
//...
};
If you want to stop the repetitive typing then this might be a solution.
When you want to catch your exceptions, you write something like this:
catch (...) {
handle_exception(print_message);
}
print_message is a function that does whatever you want with the message (in this case, print it):
void print_message(char const* const msg)
{
std::cout << msg;
}
handle_exception is written like this:
template<typename F>
void handle_exception(F handler)
try {
throw;
}
catch (InvalidArgumentsError const& ex) {
handler(ex.parameter.c_str());
}
catch (ServerInternalError const& ex) {
handler(ex.parameter.c_str());
}
catch (NoDataError const& ex) {
handler(ex.parameter.c_str());
}
catch (apache::thrift::TException const& ex) {
handler(ex.what());
}
catch (std::exception const& ex) {
handler(ex.what());
}
To handle a new exception you add it to the catch clauses of the handle_exception function.
Albeit this does not really answer the question literally (#Simple did a good job at this already) I would like to propose a somewhat different approach.
Given the code posted above:
exception InvalidArgumentsError {
1: string parameter
}
exception ServerInternalError {
1: string parameter
}
exception NoDataError {
1: string parameter
}
If we look at the pattern, we could - without loosing any information and without producing greater incompatibilities - change it into this:
enum ErrorCode
Success = 0, // always good to have some null value
ServerInternalError = 1
NoData = 2
InvalidArguments = 3
// add more errors here
}
exception MyServiceException {
1: string parameter
2: ErrorCode code
}
I'm fully aware that this might not fit your particular problem (e.g. if there are more exception data than just a 1:parameter). But there may be cases where that approach could be worth considering. I've used it myself quite a few times.

Unhandled exception, even after adding try-catch block ? C++

try
{
bool numericname=false;
std::cout <<"\n\nEnter the Name of Customer: ";
std::getline(cin,Name);
std::cout<<"\nEnter the Number of Customer: ";
std::cin>>Number;
std::string::iterator i=Name.begin();
while(i!=Name.end())
{
if(isdigit(*i))
{
numericname=true;
}
i++;
}
if(numericname)
{
throw "Name cannot be numeric.";
}
} catch(string message)
{
cout<<"\nError Found: "<< message <<"\n\n";
}
Why am I getting unhandled exception error ? Even after I have added the catch block to catch thrown string messages?
"Name cannot be numeric." is not a std::string, it's a const char*, so you need to catch it like this:
try
{
throw "foo";
}
catch (const char* message)
{
std::cout << message;
}
To catch "foo" as std::string you need to throw/catch it like this:
try
{
throw std::string("foo");
}
catch (std::string message)
{
std::cout << message;
}
You should send an std::exception instead, like throw std::logic_error("Name cannot be numeric")
you could then catch it with polymorphsim and the underlying type of your throw will no more be a problem :
try
{
throw std::logic_error("Name cannot be numeric");
// this can later be any type derived from std::exception
}
catch (std::exception& message)
{
std::cout << message.what();
}

c++: Catch runtime_error

I am learning c++ at home and I am using the rapidxml lib.
I am using the utils provided with it to open files:
rapidxml::file<char> myfile (&filechars[0]);
I noticed that if filechars is wrong the rapidxml::file throw a runtime_error:
// Open stream
basic_ifstream<Ch> stream(filename, ios::binary);
if (!stream)
throw runtime_error(string("cannot open file ") + filename);
stream.unsetf(ios::skipws);
I think I need to write something like that:
try
{
rapidxml::file<char> GpxFile (pcharfilename);
}
catch ???
{
???
}
I made some googling, but I did not find what I need in the place of the ???.
Could somebody help me?
Thanks!
You need to add an exception declaration next to the catch statement. The type thrown is std::runtime_error.
try
{
rapidxml::file<char> GpxFile (pcharfilename);
}
catch (const runtime_error& error)
{
// your error handling code here
}
If you need to catch multiple, different kinds of exceptions, then you can tack on more than one catch statement:
try
{
rapidxml::file<char> GpxFile (pcharfilename);
}
catch (const runtime_error& error)
{
// your error handling code here
}
catch (const std::out_of_range& another_error)
{
// different error handling code
}
catch (...)
{
// if an exception is thrown that is neither a runtime_error nor
// an out_of_range, then this block will execute
}
try
{
throw std::runtime_error("Hi");
}
catch(std::runtime_error& e)
{
cout << e.what() << "\n";
}
Well, it depends on what you want to do when it happens. This is the minimum:
try
{
rapidxml::file<char> GpxFile (pcharfilename);
}
catch (...)
{
cout << "Got an exception!"
}
If you want to get at the actual exception, then you need to declare a variable to store it in inside the parentheses in place of the three dots.

Catching all unhandled C++ exceptions?

Is there some way to catch exceptions which are otherwise unhandled (including those thrown outside the catch block)?
I'm not really concerned about all the normal cleanup stuff done with exceptions, just that I can catch it, write it to log/notify the user and exit the program, since the exceptions in these casese are generaly fatal, unrecoverable errors.
something like:
global_catch()
{
MessageBox(NULL,L"Fatal Error", L"A fatal error has occured. Sorry for any inconvience", MB_ICONERROR);
exit(-1);
}
global_catch(Exception *except)
{
MessageBox(NULL,L"Fatal Error", except->ToString(), MB_ICONERROR);
exit(-1);
}
This can be used to catch unexpected exceptions.
catch (...)
{
std::cout << "OMG! an unexpected exception has been caught" << std::endl;
}
Without a try catch block, I don't think you can catch exceptions, so structure your program so the exception thowing code is under the control of a try/catch.
Check out std::set_terminate()
Edit: Here's a full-fledged example with exception matching:
#include <iostream>
#include <exception>
#include <stdexcept>
struct FooException: std::runtime_error {
FooException(const std::string& what): std::runtime_error(what) {}
};
int main() {
std::set_terminate([]() {
try {
std::rethrow_exception(std::current_exception());
} catch (const FooException& e) {
std::cerr << "Unhandled FooException: " << e.what() << std::endl;
} catch (const std::exception& e) {
std::cerr << "Unhandled exception: " << e.what() << std::endl;
} catch (...) {
std::cerr << "Unhandled exception of unknown type" << std::endl;
}
std::abort();
});
throw FooException("Bad things have happened.");
// throw std::runtime_error("Bad things have happened.");
// throw 9001;
}
You can use SetUnhandledExceptionFilter on Windows, which will catch all unhandled SEH exceptions.
Generally this will be sufficient for all your problems as IIRC all the C++ exceptions are implemented as SEH.
Without any catch block, you won't catch any exceptions. You can have a catch(...) block in your main() (and its equivalent in each additional thread). In this catch block you can recover the exception details and you can do something about them, like logging and exit.
However, there are also downside about a general catch(...) block: the system finds that the exception has been handled by you, so it does not give any more help. On Unix/Linux, this help would constitute creating a CORE file, which you could load into the debugger and see the original location of the unexcepted exception. If you are handling it with catch(...) this information would be already lost.
On Windows, there are no CORE files, so I would suggest to have the catch(...) block. From that block, you would typically call a function to resurrect the actual exception:
std::string ResurrectException()
try {
throw;
} catch (const std::exception& e) {
return e.what();
} catch (your_custom_exception_type& e) {
return e.ToString();
} catch(...) {
return "Ünknown exception!";
}
}
int main() {
try {
// your code here
} catch(...) {
std::string message = ResurrectException();
std::cerr << "Fatal exception: " << message << "\n";
}
}
Update: This covers c++98 only.
From More Effective C++ by Meyers (pg 76), you could define a function that gets called when a function generates an exception that is not defined by its exception specification.
void convertUnexpected()
{
// You could redefine the exception here into a known exception
// throw UnexpectedException();
// ... or I suppose you could log an error and exit.
}
In your application register the function:
std::set_unexpected( convertUnexpected );
Your function convertUnexpected() will get called if a function generates an exception that is not defined by its exception specification... which means this only works if you are using exception specifications. ;(
Provided that C++11 is available, this approach may be used (see example from: http://en.cppreference.com/w/cpp/error/rethrow_exception):
#include <iostream>
#include <exception>
void onterminate() {
try {
auto unknown = std::current_exception();
if (unknown) {
std::rethrow_exception(unknown);
} else {
std::cerr << "normal termination" << std::endl;
}
} catch (const std::exception& e) { // for proper `std::` exceptions
std::cerr << "unexpected exception: " << e.what() << std::endl;
} catch (...) { // last resort for things like `throw 1;`
std::cerr << "unknown exception" << std::endl;
}
}
int main () {
std::set_terminate(onterminate); // set custom terminate handler
// code which may throw...
return 0;
}
This approach also allows you to customize console output for unhandled exceptions: to have something like this
unexpected exception: wrong input parameters
Aborted
instead of this:
terminate called after throwing an instance of 'std::logic_error'
what(): wrong input parameters
Aborted
This is what I always do in main()
int main()
{
try
{
// Do Work
}
catch(std::exception const& e)
{
Log(e.what());
// If you are feeling mad (not in main) you could rethrow!
}
catch(...)
{
Log("UNKNOWN EXCEPTION");
// If you are feeling mad (not in main) you could rethrow!
}
}
Use catch (...) in all of your exception barriers (not just the main thread). I suggest that you always rethrow (...) and redirect standard output/error to the log file, as you can't do meaningful RTTI on (...). OTOH, compiler like GCC will output a fairly detailed description about the unhandled exception: the type, the value of what() etc.