Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Catch Multiple Custom Exceptions? - C++

I'm a student in my first C++ programming class, and I'm working on a project where we have to create multiple custom exception classes, and then in one of our event handlers, use a try/catch block to handle them appropriately.

My question is: How do I catch my multiple custom exceptions in my try/catch block? GetMessage() is a custom method in my exception classes that returns the exception explanation as a std::string. Below I've included all the relevant code from my project.

Thanks for your help!

try/catch block


    // This is in one of my event handlers, newEnd is a wxTextCtrl try {     first.ValidateData();     newEndT = first.ComputeEndTime();     *newEnd << newEndT; } catch (// don't know what do to here) {     wxMessageBox(_(e.GetMessage()),                   _("Something Went Wrong!"),                  wxOK | wxICON_INFORMATION, this);; } 

ValidateData() Method


void Time::ValidateData() {     int startHours, startMins, endHours, endMins;      startHours = startTime / MINUTES_TO_HOURS;     startMins = startTime % MINUTES_TO_HOURS;     endHours = endTime / MINUTES_TO_HOURS;     endMins = endTime % MINUTES_TO_HOURS;      if (!(startHours <= HOURS_MAX && startHours >= HOURS_MIN))         throw new HourOutOfRangeException("Beginning Time Hour Out of Range!");     if (!(endHours <= HOURS_MAX && endHours >= HOURS_MIN))         throw new HourOutOfRangeException("Ending Time Hour Out of Range!");     if (!(startMins <= MINUTE_MAX && startMins >= MINUTE_MIN))         throw new MinuteOutOfRangeException("Starting Time Minute Out of    Range!");     if (!(endMins <= MINUTE_MAX && endMins >= MINUTE_MIN))         throw new MinuteOutOfRangeException("Ending Time Minute Out of Range!");     if(!(timeDifference <= P_MAX && timeDifference >= P_MIN))         throw new PercentageOutOfRangeException("Percentage Change Out of Range!");     if (!(startTime < endTime))         throw new StartEndException("Start Time Cannot Be Less Than End Time!"); } 

Just one of my custom exception classes, the others have the same structure as this one


class HourOutOfRangeException { public:         // param constructor         // initializes message to passed paramater         // preconditions - param will be a string         // postconditions - message will be initialized         // params a string         // no return type         HourOutOfRangeException(string pMessage) : message(pMessage) {}         // GetMessage is getter for var message         // params none         // preconditions - none         // postconditions - none         // returns string         string GetMessage() { return message; }         // destructor         ~HourOutOfRangeException() {} private:         string message; }; 
like image 731
Alex Avatar asked Mar 25 '10 03:03

Alex


2 Answers

If you have multiple exception types, and assuming there's a hierarchy of exceptions (and all derived publicly from some subclass of std::exception,) start from the most specific and continue to more general:

try {     // throws something } catch ( const MostSpecificException& e ) {     // handle custom exception } catch ( const LessSpecificException& e ) {     // handle custom exception } catch ( const std::exception& e ) {     // standard exceptions } catch ( ... ) {     // everything else } 

On the other hand, if you are interested in just the error message - throw same exception, say std::runtime_error with different messages, and then catch that:

try {     // code throws some subclass of std::exception } catch ( const std::exception& e ) {     std::cerr << "ERROR: " << e.what() << std::endl; } 

Also remember - throw by value, catch by [const] reference.

like image 165
Nikolai Fetissov Avatar answered Oct 12 '22 12:10

Nikolai Fetissov


You should create a base exception class and have all of your specific exceptions derive from it:

class BaseException { }; class HourOutOfRangeException : public BaseException { }; class MinuteOutOfRangeException : public BaseException { }; 

You can then catch all of them in a single catch block:

catch (const BaseException& e) { } 

If you want to be able to call GetMessage, you'll need to either:

  • place that logic into BaseException, or
  • make GetMessage a virtual member function in BaseException and override it in each of the derived exception classes.

You might also consider having your exceptions derive from one of the standard library exceptions, like std::runtime_error and use the idiomatic what() member function instead of GetMessage().

like image 35
James McNellis Avatar answered Oct 12 '22 14:10

James McNellis