Thread: Exceptions -Can I use catch definition multiple times?

  1. #1
    Registered User
    Join Date
    Sep 2011
    Posts
    1

    Exceptions -Can I use catch definition multiple times?

    I am using a catch statement multiple times. Is there a format so I don't have to use define the catch statement multiple times?

    Here is my layout...
    Code:
    header.h
    
    class someClass {
    ... 
    class theThrow{};
    ...
    }
    //end of file
    
    
    definitions.cpp
    ... 
    someClass::someFunction(int a){
          if(a > o) {
          throw theThrow{
      }
    }
    ...
    //end of file
    
    program.cpp
    ...
    try
    {
       int a = 1;
       someFunction(a);
    }
    catch
    {
       //all the catch code or function
    }
    ...
    try
    {
       int b = 2;
       someFunction(b);
    {
    catch
    {
    //now I have to type all the catch code or function over again
    }
    ...
    Is there anyway to define the catch and then just have it automatically pull the catch?

    I know I can just put a function in the catch which will save some time but is that the best style?

  2. #2
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    you can have a try/catch block in your main() function so that any unhandled exception gets caught there. otherwise, you can have a whole function body inside a try block with its own catch. you can even define multiple catch blocks for a single try block for different types of exceptions.

    example:
    Code:
    #include <iostream>
    #include <stdexcept>
    #include <string>
    using namespace std;
    
    class myException : public exception
    {
    public:
      myException(const std::string& msg) throw() : exception(), m_msg(msg) {  }
      virtual ~myException() throw() {  }
      const char* what() throw() { return m_msg.c_str(); }
    private:
      std::string m_msg;
    };
    
    int func1(int arg)
    {
      if (arg != 0)
        throw invalid_argument("arg must be zero");
      return arg;
    }
    
    int func2(int arg)
    {
      if (arg > 10 || arg < 1)
        throw range_error("arg must be greater than zero, and not more than ten");
      return arg;
    }
    
    int func3(int arg)
    {
      if (arg > 10)
        throw myException("custom exception type");
      return arg;
    }
    
    int main()
    {
      try
      {
      	func1(1);
      	func2(0);
      	func3(11);
      }
      catch (invalid_argument& ia)
      {
        cout << ia.what() << endl;
      }
      catch (range_error& re)
      {
        cout << re.what() << endl;
      }
      catch (exception& ex)
      {
      	cout << "something else was thrown" << endl;
      }
    }

  3. #3
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Elkvis's is a good one when there aren't other reasons to keep your try blocks separate. Consider this first.

    Next on the list to consider is, as you say, writing a function that goes in your catch blocks. This will prevent duplicate code, without interfering with the location of your try block.

    That might not do enough however if your exception handling uses multiple catch blocks for different types: you can't move the catch blocks to a function. Therefore last you could consider using a macro. Macro's are ugly on account of being different from the rest of the language, and are harder to debug because you don't get syntax highlighting and line numbers (effectively), however they do consolidate code, so you're not writing the same thing more than once.

    And not repeating code is important, because it makes it easier to change. If you have the same code in multiple places, and you find an error or add a feature to one part, then often you want that fix or extension to apply to all the places where identical code is used. Doing this manually leads to errors. Using the tools of the language to do it is preferred.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  4. #4
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    O_o

    The most important question here is whether or not the program logic holds in the case of a portion of the logic failing.

    Soma

    Code:
    // ...
    {
        try
        {
            Go1();
        }
        catch(...)
        {
            // ...
        }
        try
        {
            // If `Go1' fails, does this make sense?
            // How does this make sense?
            // Did the `catch' block above realign global state?
            // If the global state can be realigned in the case of an exception at local scope,
            // was there even an exception?
            // Did the `catch' block above simply log an error so that we may continue in any event?
            // If the the `catch' block only exists to log an error the failure of the function isn't critical,
            // so why don't we just wrap that function to emit a log entry and continue normally without needing
            // the logic every time that function is used?
            // Did we loop until we succeeded?
            // If we must succeed in order to get here, why do we do anything locally with an exception
            // when we can't guarantee eventual success? Shouldn't we let higher order logic determine further attempts?
            Go2();
        }
        catch(...)
        {
            // ...
        }
    }
    // ...

  5. #5
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    If you are trying to reuse an exception handler, then one technique is
    Code:
    //   in one place
    try
    {
        // code that may throw
    }
    catch (...)
    {
         handle_my_exceptions();
    }
    
    // in another place (including in another source file)
    
    try
    {
        // other code that may throw
    }
    catch (...)
    {
         handle_my_exceptions();
    }
    
    
    //   now the handler
    
    void handle_my_exceptions()
    {
          try
          {
                throw;     // rethrow the exception
          }
          catch(some_exception &e)
          {
               // handle some_exception
          }
           catch(some_other_exception &e)
          {
               // handle some_other_exception
          }
          catch (...)
          {
                // handle all other exceptions
          }   
    }
    This allows reuse of exception handling code. The technique, inside handle_my_exceptions() is to rethrow the active exception, and catch it in order to handle it.

    The weakness is that, if handle_my_exceptions() is called outside of an exception handler (i.e. there is no active exception) then the program will abort().
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. using /dev/urandom multiple times
    By miutsu in forum C Programming
    Replies: 6
    Last Post: 11-20-2010, 03:12 PM
  2. Multiple definition error, one definition
    By frog in forum C++ Programming
    Replies: 9
    Last Post: 10-21-2010, 03:15 AM
  3. Exceptions "try, catch, and throw Statements" ???
    By Loic in forum C++ Programming
    Replies: 2
    Last Post: 08-12-2008, 09:22 PM
  4. Need advice: catch exceptions or call methods to check bits?
    By registering in forum C++ Programming
    Replies: 1
    Last Post: 10-03-2003, 01:49 PM
  5. try/catch/throw exceptions
    By smd in forum C++ Programming
    Replies: 3
    Last Post: 07-02-2002, 08:44 AM