How to build a custom string inside what() function of exception class and return it? The following code does not work but presents what I want to achieve:
class divide_by_zero : public exception {
public:
divide_by_zero(int a) : a(a) {}
const char * what() noexcept {
stringstream ss;
ss << "Division " << a << " by zero!";
return ss.str().c_str();
}
private:
int a;
};
How to build a custom string inside what() function of exception class and return it?
Don't do that. It won't work.
Instead, build the custom string inside the constructor, store the string in a member, and return a pointer to the data owned by the member in what.
Technically, you can delay building the string until the first call to what. The primarily important thing is to store the string in a member rather than a local variable, and to not invalidate the returned pointer. Such delay is unnecessary complexity however, it is simpler to build the string in the constructor.
Your local stringstream is being destroyed too early as it's only local.
Cache the message result with the exception object.
#include <iostream>
#include <stdexcept>
#include <sstream>
#include <string>
using std::cout;
using std::exception;
using std::stringstream;
using std::string;
class divide_by_zero : public exception {
public:
divide_by_zero(int aa) : a{aa} {}
const char * what() const noexcept override {
if (msg.empty()) {
stringstream ss;
ss << "Division " << a << " by zero!";
msg = ss.str();
}
return msg.c_str();
}
private:
int a;
mutable string msg;
};
int main() {
try {
throw divide_by_zero(75);
} catch(exception const& ex) {
cout << "Caught exception " << ex.what() << "\n";
}
}
UPDATE, or use eerorika's recommendation:
#include <iostream>
#include <stdexcept>
#include <sstream>
#include <string>
using std::cout;
using std::exception;
using std::stringstream;
using std::string;
class divide_by_zero : public exception {
public:
divide_by_zero(int a) : msg{make_msg(a)} {}
char const* what() const noexcept override {
return msg.c_str();
}
private:
string msg;
static string make_msg(int a) {
stringstream ss;
ss << "Division " << a << " by zero!";
return ss.str();
}
};
int main() {
try {
throw divide_by_zero(75);
} catch(exception const& ex) {
cout << "Caught exception " << ex.what() << "\n";
}
}
You can format and store that string in the constructor and return it later on:
#include <cstdio>
#include <exception>
class divide_by_zero : public std::exception {
public:
divide_by_zero(int const a) {
std::sprintf(buff, formatStr, a);
}
const char * what() const noexcept override {
return buff;
}
private:
static constexpr auto& formatStr = "Division %d by zero!";
char buff[sizeof(formatStr) + 20];
};
This does no dynamic allocation, which is better in the case of exception handling.
Related
#include <iostream>
#include <sstream>
using std::string;
using std::cout;
using std::endl;
using std::ostringstream;
class illegalParameterValue {
private:
string message;
public:
illegalParameterValue() : message("Illegal parameter value") {}
explicit illegalParameterValue(const char* theMessage) {message = theMessage;}
void outputMessage() {cout << message << endl;}
};
int main() {
ostringstream s;
s << "index = " << 1 << " size = " << 2;
throw illegalParameterValue(s.str().c_str());
return 0;
}
I just use some code like this, but the throw will remind some warnings which called
Clang-Tidy: Throwing an exception whose type 'illegalParameterValue' is not derived from 'std::exception'
How can I solve this problem?
consider the following code:
try {
// do something that might throw an exception
}
catch (const std::exception &ex) {
// handle the exception
}
If you derive your illegalParameterValue class from std::exception, then the catch clause above will catch it (along with other kinds of exceptions derived from std::exception). As currently written, it will not. Your users will have to add another catch clause:
try {
// do something that might throw an exception
}
catch (const std::exception &ex) {
// handle std exceptions
}
catch (const illegalParameterValue &ip) {
// handle illegal parameter exeception
}
Maybe that's what you want, maybe not.
But there's a lot of code out there like the first case.
I'm trying to create a class with a method to handle all exceptions. It accepts a pointer to a function, executes that function and then will handle if the function throws an exception. I then created a function get an invalid substring to prove the exception is caught, however, my class isn't getting the exception and Visual Studio is breaking on the substring line saying "Exception Unhandled"
cpp file:
#include "TestHarness.h"
using namespace TestHarness;
int testFunc();
int main()
{
Tester myTest;
std::cout << myTest.execute(testFunc);
return 0;
}
int testFunc()
{
std::cout << "My Test Func" << std::endl << std::endl;
std::string("abc").substr(10);
return 6;
}
h file:
#define TESTHARNESS_H
#include <vector>
#include <iostream>
#include <sstream>
#include <string>
namespace TestHarness
{
class Tester
{
public:
int execute(int(*func)());
private:
bool result;
};
int Tester::execute(int(*func)())
{
try {
(*func)();
result = true;
return 1;
}
catch (const std::runtime_error& e)
{
std::cout << e.what();
result = false;
return 0;
}
}
}
#endif
It's simple, really: substr throws std::out_of_range, which does not derive from std::runtime_error but from std::logic_error, itself derived from std::exception. Just catch std::exception const & or std::logic_error const &. Here is a list of inheritance for all standard exception types.
I'm currently using caffe but I'm facing a problem. Sometime the library call LOG(FATAL) but I would like to raise an exception and catch it.
I have tried to do my own class defined as below:
#include <stdexcept>
#include <iostream>
#include <sstream>
class FatalException
{
private:
std::stringstream _ss;
public:
template<typename T>
std::ostream& operator<<(const T& obj){
_ss << obj;
return _ss;
}
~FatalException(){
throw std::runtime_error(_ss.str().c_str());
}
};
The problem is that when I'm doing some testing such as
int main() {
try {
FatalException() << "test";
}
catch(...) {
std::cout << "here" << std::endl;
}
}
the exception is thrown after the try scope
Do you have any hints?
Should I overload a stream class and throw an exception when the stream is flushed?
I'm running code which might throw a boost:bad_lexical_cast when casting a sequence of tokens - but I can't go into the code and "put the tokens aside" so I can figure out what cast actually failed.
Does boost:bad_lexical_cast let you access that string it had attempted to cast somehow? I could not seem to find anything in its definition except for some fields regarding type names, but maybe there's something I'm missing.
if you have control of the code that calls lexical_cast, then you can use function try blocks to catch, wrap and re-throw the exception with extra information:
#include <boost/lexical_cast.hpp>
#include <string>
#include <stdexcept>
#include <exception>
struct conversion_error : std::runtime_error
{
conversion_error(const std::string& name, const std::string& value)
: std::runtime_error::runtime_error("converting " + name + " : " + value)
, name(name)
, value(value)
{}
const std::string name, value;
};
struct test
{
void bar()
{
try {
foo();
} catch(const conversion_error& e) {
std::cerr << e.what() << std::endl;
}
}
void foo()
try
{
i = boost::lexical_cast<int>(s);
}
catch(...)
{
std::throw_with_nested(conversion_error("s", s));
}
std::string s;
int i;
};
int main()
{
test a { "y", 0 };
a.bar();
}
i was writing a class like this
class AA{
private:
char* str;
public:
AA(int size){
str = (char*)malloc(size);
}
};
int main(){
AA anAA(1000);
}
here is the problem, when the size is too big it may cause malloc return a 0 pointer, if the str init fail, is there any method to return a 0 pointer to anAA(in the main entry point, i can check anAA isn't init success by if(anAA != NULL)), i don't want to make a function for creating AA class, or make a check function in the class
I'll ignore the atrocities you are committing in favour of answering your question.
The easiest solution, if you don't want to use exceptions, is to define an operator bool():
class AA{
...
public:
operator bool() const {
return this->str != nullptr; // return str; would actually suffice
}
};
int main(){
AA anAA(1000);
if (!anAA) {
std::cerr << "Creating object failed.\n";
return 1;
}
return 0;
}
#include <iostream>
#include <stdexcept> // std::exception
#include <stdlib.h> // EXIT_FAILURE
#include <string> // std::string
#include <vector> // std::vector
using namespace std;
class AA{
private:
string str_;
public:
AA( int const size)
{
str_.reserve( size );
}
};
int main()
{
try
{
AA anAA( 1000 );
// Whatever
}
catch( exception const& x )
{
cerr << "!" << x.what() << endl;
return EXIT_FAILURE;
}
}
Note 1: with this approach you probably don't need to reserve a size upfront.
Note 2: I chose reserve as probably the closest thing to a presumed intention of making sure that str_ can hold at least that long a string without failure, a preallocation of resources.
Disclaimer: I've not compiled this code.