The_Questioner
The_Questioner

Reputation: 312

c++ - Throwing multiple exceptions of the same type

So I've got a program with two exception. In both cases, I'd like to throw a string that can be caught in the main function and used in an error message. However, from what I know about them

    try {
     ...
    } catch(string msg) {
     cerr << "..." << msg << "..." << endl;
    } catch (string msg2) {
     cerr << "..." << msg2 << "..." << endl;
    }

isn't allowed. Is there any way I could do the above or something like it? Thanks

Upvotes: 0

Views: 10213

Answers (3)

Pixelchemist
Pixelchemist

Reputation: 24966

I see two use cases:

1. You want two distinct types of errors.

Add exception classes derived from std::exception

class MyException1 : public std::exception
{
  std::string message;
public:
  MyException1(std::string const &what_arg) : message(what_arg) {}
  MyException1(char const * what_arg) : message(what_arg) {}
  const char* what() const { return message.c_str(); }
};

class MyException2 : public std::exception
{
  std::string message;
public:
  MyException2(std::string const &what_arg) : message(what_arg) {}
  MyException2(char const * what_arg) : message(what_arg) {}
  const char* what() const { return message.c_str(); }
};

and catch those:

try
{

  int a = 5;

  // do stuff

  if (a == 7)
  {
    throw MyException1("Error 1 occured in  because a == 7.");
  }
  else if (a == 5)
  {
    throw MyException1("Error 1 occured because a == 5.");
  }

  // do more stuff

  if (a == 22)
  {
    throw MyException2("Error 2 occured in  because a == 22.");
  }
  else if (a == 575)
  {
    throw MyException2("Error 2 occured because a == 575.");
  }

}
catch (MyException1 &ex)
{
  std::cout << "Exception 1: " << ex.what() << "\n";
}
catch (MyException2 &ex)
{
  std::cout << "Exception 2: " << ex.what() << "\n";
}

Note: This is an easy but not the best design for a custom exception since std::string may throw and your program will be terminated.

2. You want two different error messages:

Use the appropriate type of exception from <stdexcept> header:

try
{

  int a = 5;
  // do stuff
  if (a == 7)
  {
    throw std::runtime_error("Error 1 occured because a == 7.");
  }
  else if (a == 5)
  {
    throw std::runtime_error("Error 2 occured because a == 5.");
  }

}
catch (const std::exception &ex)
{
  std::cout << "Exception: " << ex.what() << "\n";
}

Note: The behaviour of case 1 can be emulated in case 2 without own types if the only desired behaviour is different output:

try
{

  int a = 5;
  // do stuff
  if (a == 7)
  {
    throw std::runtime_error("Exception 1: Error 1 occured in  because a == 7.");
  }
  else if (a == 5)
  {
    throw std::runtime_error("Exception 1: Error 1 occured because a == 5.");
  }
  // do more stuff
  if (a == 22)
  {
    throw std::runtime_error("Exception 2: Error 2 occured in  because a == 22.");
  }
  else if (a == 575)
  {
    throw std::runtime_error("Exception 2: Error 2 occured because a == 575.");
  }

}
catch (const std::exception &ex)
{
  std::cout << ex.what() << "\n";
}

Upvotes: 6

WhiZTiM
WhiZTiM

Reputation: 21576

First: Your compiler is supposed to issue a warning for that, because, the second catch will never be executed, because they are of exact signatures. Besides, you cannot have a second exception being thrown while the first is active ( exception thrown during stack unwinding that hasn't entered a catch block yet), else, the runtime will terminate your program.

Secondly: prefer to catch your exceptions by reference

Thirdly: Prefer to have your exception object fall in the inheritance tree of std::exception.

Lastly: What the hell are you trying to do?

Upvotes: 0

Charlie OConor
Charlie OConor

Reputation: 867

Use std::runtime_error it has a constructor that takes a string. So pass it a different value when it is throw.

 throw runtime_error( "msg1");

 ...

 throw runtime_error("msg2");

Then when you catch just print the message in the object

 ...
 catch( exception& e ){
     cout << e.what() << endl;
 }

Upvotes: 2

Related Questions