Developing Custom Exception Handler :: C++

Started by
10 comments, last by kuphryn 22 years, 1 month ago
Hi. I would like to create a custom class exception handler. I want to use it for arbitrary exceptions that are not part of the exception library. I am having a problem with such a class. Here is the code for that exception class. ----- #ifndef CEXCEPTIONHANDLE_H #define CEXCEPTIONHANDLE_H class ExceptionHandle { public: ExceptionHandle(const char *error) : eMessage(error) {} const char *what() const throw() { return eMessage; } private: const char *eMessage; }; #endif ----- I basic want to *throw* a character string to the exception handle. Afterward, have a catch function to call what(). Here is an example of a try/catch. ---- try { function(x); } catch (ExceptionHandle *e) { cerr << e->what(); } ----- function(int X) { if (X == 0) throw ExceptionHandle("Error: X equals zero."); } ----- The program I am working on works, but it crashes whenever "throw ExceptionHandle("Error: X equals zero.");" occurs. Does anyone know what is wrong with my design and/or implementation? Thanks, Kuphryn
Advertisement
The only idea I have is that your constructor should also be qualified as const throw(), just like your what() method.

On another note, though, you are supposed to inherit from std::exception. It makes your code better integrate with the STL and other applications that do not provide exception-specific handling (they can simply catch the base case).

#include <stdexcept>#include <string>//// You should probably find a better name for this class too class ExceptionHandle : public std::exception{public:  ExceptionHandle(const std::string error) const throw()  : m_err(error)  {  }//  virtual cons char *what() const throw()  {    return m_err.c_str();  }//private:  std::string m_err;}; 

You can also choose to implement more of the std::exception interface.

[ GDNet Start Here | GDNet Search Tool | GDNet FAQ | MS RTFM [MSDN] | SGI STL Docs | Google! ]
Thanks to Kylotan for the idea!
maybe you should put
try
{
function(x)
}
catch(ExceptionHandle e)
{
cerr<}


If that doesn''t work, you could always debug with
try {
function(x);
}
catch(ExceptionHandle* e)
{
//did we catch an ExceptionHandle* ?
}
catch(unexpected_exception)
{
//are we throwing an unexpected exception?
}
Okay. Thanks.

Visual C++ debugger kept point to the "throw" code as the source of the crash.

-----
throw ExceptionHandle("Error: X equals zero.");
-----

It pointed to that line. I did not add "const throw ()" to the constructor. I will try that tomorrow because I can barely open my eyes.

I''ll post an update.

Kuphryn
Maybe I''m missing something obvious here ... but if you are using
catch (ExceptionHandle *e)

Shouldn''t you be using
throw new ExceptionHandle("Error: X equals zero.") ?
ReactOS - an Open-source operating system compatible with Windows NT apps and drivers
Good point Martee. I typically use catch(std::exception &e) so I don''t necessarily have to use new...

[ GDNet Start Here | GDNet Search Tool | GDNet FAQ | MS RTFM [MSDN] | SGI STL Docs | Google! ]
Thanks to Kylotan for the idea!
Okay. Thanks.

I believe the problem was due to these pointer related calls:

-----
const char *eMessage
-----

and/or

-----
catch (ExceptionHandle *e)
-----

I will do two things.

1) I will replace "const char *eMessage" with "const string eMessage."
2) I will replace "catch (ExceptionHandle *e)" with "catch (ExceptionHandle &e)."

First, is the problem caused by "*e" pointing to something that no longer exists? How can that be if I am throwing an exception each time?

I can also add "new" to "throw...new" as Martee mentioned.

Which ones of these changes should *fix* the problem most elegantly?

Thanks,
Kuphryn

Edited by - kuphryn on February 20, 2002 10:11:38 AM
Always catch exception by reference!

Reasons :

1. You do not need to call new and delete( because if you catch an exception and your program keeps going you will leak if you do not call delete on your exception. )

2. No slicing problems :
If you have hierarchy of classes for exceptions, and you only catch the base one by value, the destructor of the derived class won''t be correclty called and the overload what() functions also won''t be called.

ex.

       class ExceptionBase       {           virtual char* what();        }        class DerivedException:public ExceptionBase        {               virtual char* what();         }try{..} catch( ExceptionBase e){          std::cout << e.what() ; // uses exceptionBase.what() not DerivedException.what()} 


So always catch by refence!
Never throw pointers. MFC did this and it just makes things a mess. Why burder your exception handler with the responsibility of deleting the exception object?

Exceptions are supposed to be slow, so do it the robust way: give your exception a good copy constructor and assignment operator, throw an object and catch a reference. If you need to change the exception, create a copy and throw that.

Also, you should definitely be deriving from the std::exception that most fits your error (runtime_error, logic_error, etc.) since your usage almost matches theirs exactly.
By the way, the ''handler'' is the code that deals with the exception. What you are writing is just an ''exception'' itself.

std::exception does most of what you want anyway, I believe.

[ MSVC Fixes | STL | SDL | Game AI | Sockets | C++ Faq Lite | Boost ]

This topic is closed to new replies.

Advertisement