C++ Exception - Throw a String
Asked Answered
M

4

21

I'm having a small issue with my code. For some reason, when I try to throw a string with the code below, I get an error in Visual Studio.

#include <string>
#include <iostream>
using namespace std;

int main()
{
    
    char input;

    cout << "\n\nWould you like to input? (y/n): ";
    cin >> input;
    input = tolower(input);

    try
    {
        if (input != 'y')
        {
            throw ("exception ! error");
        }
    }
    catch (string e)
    {
        cout << e << endl;
    }
}

Error :

error

Musjid answered 27/11, 2014 at 21:40 Comment(1)
If you want to catch a string, throw a string and not a string literal. Otherwise catch a const char*. Although it would be a better idea to use one of the exception classes.Hydropic
W
24

You are currently throwing a const char* and not a std::string, instead you should be throwing string("error")

edit: the error is resolved with

throw string("exception ! error");
Whoredom answered 27/11, 2014 at 21:42 Comment(3)
Yes , but its catching: throw ("exception ! error"); which is a stringMusjid
@Musjid yes, so it's not finding a case for catching a const char*Whoredom
@SyntacticFructose - This is dangerous (throwing/catching a std::string by value), since a string has to be constructed, which may throw an error. The string should be caught by reference.Simplehearted
P
28

Throwing a string is really a bad idea.

In your code you are throwing a const char*. Throwing a built-in type (like an int, or float, or a const char* like in this case) is a bad idea because these built-in types don't carry proper contextual error information. In fact, when an exception is caught, it's important to understand the reason for the exception to take proper action. But a built-in type doesn't properly provide such information, making it difficult at the catch-site to understand the reason and the cause for the exception.

Moreover, throwing a built-in type is also confusing, as it's not idiomatic modern C++. The idiomatic C++ way of throwing an exception is to define a proper C++ class to represent the exception, typically deriving it from std::exception, or from some other class derived from std::exception, and then throw an instance of such exception class. You could also simply throw some of the C++ exception classes already defined in the C++ Standard Library, like std::runtime_error.

For example, you could throw a std::runtime_error, passing an error message string to the constructor, like this:

throw std::runtime_error("Your error message");

and, at the catch site, you can catch the runtime_error exception by const reference (const &), and invoke the what() method to get the error string.

try {
    ...
} catch (const std::runtime_error& ex) {
    // Invoke ex.what() to get the error message
}

But do not throw the "naked" string.


In case you want to define a custom exception class, you can derive it for example from std::runtime_error like this:

class YourCustomException
    : public std::runtime_error 
{
  public:

    YourCustomException(const char* message)
        : std::runtime_error(message) {
    }

    YourCustomException(const std::string& message)
        : std::runtime_error(message) {
    }
};

throw it like this:

throw YourCustomException("Your error message");

and catch it like this:

try {
    ...
} catch (const YourCustomException& ex) {
    // Invoke ex.what() to get the error message
}
Pressor answered 27/11, 2014 at 21:59 Comment(7)
I agree, throwing anything not related to std::exception is a really bad idea…Dandle
Or even just throw a std::runtime_error('exception text').Metallo
Why? I appreciate the advice, but what's the reasoning?Palla
@Palla You may want to have a look at this C++ FAQ.Pressor
@Mr.C64: That page explains why it's useful to throw derivations of std::runtime_exception, and advises that it's "best to throw objects, not built-ins," but it still doesn't explain what's so bad about throwing built-ins.Palla
missing some explanation, why it's bad idea etc.Kwangju
I added a more elaborated explanation and sample code.Pressor
W
24

You are currently throwing a const char* and not a std::string, instead you should be throwing string("error")

edit: the error is resolved with

throw string("exception ! error");
Whoredom answered 27/11, 2014 at 21:42 Comment(3)
Yes , but its catching: throw ("exception ! error"); which is a stringMusjid
@Musjid yes, so it's not finding a case for catching a const char*Whoredom
@SyntacticFructose - This is dangerous (throwing/catching a std::string by value), since a string has to be constructed, which may throw an error. The string should be caught by reference.Simplehearted
A
3
#include <string>
#include <iostream>
using namespace std;

int main()  
{
    
    char input;

    cout << "\n\nWould you like to input? (y/n): ";
    cin >> input;
    input = tolower(input);

    try
    {
        if (input != 'y')
        {
            throw std::runtime_error("Exception ! Error");
        }
    }

    catch(const std::exception& e)
    {
        std::cout << "Caught exception: " << e.what() << '\n';
    }
}
Arnst answered 19/9, 2021 at 8:13 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Fanchon
K
-1
try
{
  if (input != 'y')
  {
    string error = "exception ! error";
    throw error;
  }
}

When you put a string in "" it is considered as a string of characters, instead assign it to a string class variable.

Kurr answered 30/4 at 6:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.