   Elegant exception handling?
  I have some code(C++) to maintain that looks like this:try{  //a single function call that can throw many types of exception}catch(exception_type1&){   LOG("A message specific to exception_type1")   throw;}catch(exception_type2&){   LOG("A message specific to exception_type2")   throw;}catch(exception_type3&){   LOG("A message specific to exception_type2")   throw;}etc... for about 10 catch blocksCan anyone think of a more elegant way to do this?I'm not at liberty to either post the original source, or to modify the contents of the try block.   
class base_error{public:virtual std::string message()=0;};class error1 : public base_error{public:std::string message () { return std::string("ERROR 1");}};int main(){   try{throw ( new error1 );}   catch ( base_error * e )   {   std::cout<<e->message();   }return 0;}It's something like this. Doing this you loose the exact control of what to do for some errors, but it's a more clean way of just write the error to the log.   ;  Can you modify the previous post to include an enum indicating exact error type in the exception, and then switch on the enum in the catch block?class Exception { enum Type { Type1, Type2, Type3, /*...*/ } typeC;   public: Exception(Type t) : typeC(t) { } Type type() { return typeC; }   };class DerivedException1 : public Exception {   public: DerivedException() : Exception(Type1) { }   };//...catch (Exception & e) {   if (e.type() == Exception::Type1) { }   else if (e.type() == Exception::Type2) { }   //...Seems more elegant to me, even if it does add an enum that you must make sure to keep updated as your class grows.  But if you can't change the exception class and add an enum to it, I don't know what I'd do.   ;  I'd do it exactly as Xunil_RJ said. If you would create an enum for the types of exceptions, like the AP recommended, you're back where we were a decade ago using cumbersome error codes and if/switch constructs which are in no way shorter than the catch blocks you've got now. Being able to classify your errors by using derivation is one of the biggest advantages of exceptions.I'm using a preprocessor macro (one of the few cases where it makes sense) to easily declare exceptions:/** Declares a new exception class derived from the specified base.    Besides its own type, the exception class also takes a stringargument which can be set freely for extended error information*/#define DECLAREEXCEPTION(base, exception)  class exception : \public base { \  public: \    exception(const string &sSource, const string &sWhat) : \ base(sSource, sWhat) {}   };// ExampleDECLAREEXCEPTION(exception, InvalidArgumentException);  DECLAREEXCEPTION(InvalidArgumentException, WrongTypeException);  DECLAREEXCEPTION(InvalidArgumentException, ItemNotFoundException);I don't generally log exceptions, but I guess you could easily extend my preprocessor macro to write the exception type (obtained either through typeid(*this).name() or by stringifying the exception parameter of the macro) and the message to your log.-Markus-   ;  Thank for the replies everyone.Unfortunately you seem to have confirmed what I suspected. There is no way to do this elegantly without changing the exception classes - something I can't do without causing huge amounts of pain to both myself and every other developer on the project.   ;  If you really can't afford to clean up the exception classes and this is a function which is called in multiple places (or may be called in multiple places in the future) then I'd consider writing a wrapper function which translates the exceptions, i.e.:class food_error:public std::runtime_error{public:food_error(std::string const & s):std::runtime_error(s){}};class pancake_on_head_error:public food_error{public:pancake_on_head_error(exception_type1 const &):food_error("A message specific to exception_type1"){}};class waffle_overflow:public food_error{public:waffle_overflow(exception_type2 const &):food_error("A message specific to exception_type2"){}};return_type function_wrapper(parameters p){try{return wrapped_function(p);}catch (exception_type1 const & e){throw pancake_on_head_error(e);}catch (exception_type2 const & e){throw waffle_overflow(e);}// and so on}void calling_function(){try{function_wrapper(parameters());}catch (std::runtime_error const & e){LOG(e.what());throw;}}Here I've just derived from runtime_error and used the standard exception string to store the error messages but you're obviously not limited to that.Enigma   ;  All of your guys' exception structures are "incorrect". That is, they work fine, but they don't properly adhere to conventions.#define DEFINE_CUSTOM_EXCEPTION( Name, DefaultMsg ) struct Name : public std::runtime_error {    Name() throw() : std::runtime_error( DefaultMsg ) { }    Name( const std::string& Message ) : std::runtime_error( Message ) { } }(The forum is eating backslashes, but they are in there.) Note that there are two ctors, and one is a nothrow.   ;  I think the exception dispatch pattern is what you want here, assuming each exception is handled the same way each time.   ;Quote:Original post by PromitNote that there are two ctors, and one is a nothrow.std::runtime_error holds a std::string, so the throw() is misleading ( since the string constructor can throw bad_alloc which would result in a call to terminate )   