How do you construct an object that can throw exception? - c++

This is going to go out of scope so I can't use it.
try
{
SomeClass someObject({});
}
catch (std::exception & e)
{
}
someObject(x); // someObject does not exist because it goes out of scope

Here's a useful application of std::optional.
std::optional<SomeClass> maybe_someobject;
try {
maybe_someobject.emplace( /* Constructor parameters go here */);
} catch (... /* or something specific */)
{
/* catch exceptions */
return; // Do not pass "Go". Do not collect $200.
}
SomeClass &someobject=maybe_someobject.value();
// Use someobject normally, at this point. Existing code will have to look
// very hard to be able to tell the difference.
This adds a little bit overhead, but it's quite minimal, but you preserve complete type and RAII-safety.

Construct the object dynamically, eg:
SomeClass *someObject = nullptr;
try
{
someObject = new SomeClass(...);
}
catch (const std::exception &e)
{
}
// or:
// SomeClass *someObject = new(nothrow) SomeClass(...);
if (someObject)
{
// use someObject as needed...
delete someObject;
}
Alternatively:
std::unique_ptr<SomeClass> someObject;
try
{
someObject.reset(new SomeClass(...));
// or:
// someObject = std::make_unique<SomeClass>(...);
}
catch (const std::exception &e)
{
}
if (someObject)
{
// use someObject as needed...
}

Related

Gtest on new keyword

new keyword in C++ will throw an exception if insufficient memory but below code trying to return "NO_MEMORY" when new failed. This is bad because it will raise std::bad_alloc exception .
I am writing a unit test(gtest). How to create a scenario to catch this problem.
class base{
public: base(){
std::cout<<"base\n";
}
};
std::string getInstance(base** obj){
base *bObject = new base();
*obj = bObject; //updated
return (NULL == bObject) ? "NO_MEMORY" : "SUCCESS"; // here is problem if new fail it raise an exception. How to write unit test to catch this?
}
int main()
{
base *base_obj;
getInstance(&base_obj);
}
Have you looked into EXPECT_THROW?
If you cannot absolutely change your code, (which is required if you want to use gmock), you can globally overload the new operator as the other answer suggested.
However, you should do this carefully since this operator is used by other functions including the ones in google test.
One way to do this is to use a global variable that makes the new operator throw conditionally. Note that this is not the safest way, specially if your program is using multithreading
Below is one way of testing the scenario you described using this method and the global variable g_testing.
// https://stackoverflow.com/questions/70925635/gtest-on-new-keyword
#include "gtest/gtest.h"
// Global variable that indicates we are testing. In this case the global new
// operator throws.
bool g_testing = false;
// Overloading Global new operator
void *operator new(size_t sz) {
void *m = malloc(sz);
if (g_testing) {
throw std::bad_alloc();
}
return m;
}
class base {
public:
base() { std::cout << "base\n"; }
};
std::string getInstance(base **obj) {
base *bObject = new base();
*obj = bObject; // updated
return (NULL == bObject)
? "NO_MEMORY"
: "SUCCESS"; // here is problem if new fail it raise an exception.
// How to write unit test to catch this?
}
TEST(Test_New, Failure) {
base *base_obj;
// Simple usage of EXPECT_THROW. This one should THROW.
g_testing = true;
EXPECT_THROW(getInstance(&base_obj), std::bad_alloc);
g_testing = false;
std::string result1;
// You can put a block of code in it:
g_testing = true;
EXPECT_THROW({ result1 = getInstance(&base_obj); }, std::bad_alloc);
g_testing = false;
EXPECT_NE(result1, "SUCCESS");
}
TEST(Test_New, Success) {
base *base_obj;
std::string result2;
// This one should NOT throw an exception.
EXPECT_NO_THROW({ result2 = getInstance(&base_obj); });
EXPECT_EQ(result2, "SUCCESS");
}
And here is your working example: https://godbolt.org/z/xffEoW9Kd
First I think you need to catch the exception otherwise your program will never reach the point of returning NO_MEMORY:
std::string getInstance(base **obj) {
try {
if (!obj)
throw std::invalid_argument("");
*obj = new base();
return "SUCCESS";
}
catch (const std::bad_alloc& e) {
return "NO_MEMORY";
}
catch (...) {
return "UNDEFINED_ERROR";
}
}
A quick and dirty way for testing this would be to make the constructor (or an overloaded new) to throw std::bad_alloc:
#ifdef UNIT_TESTING
// simulate there is no memory
base::base() { throw std::bad_alloc; }
#else
base::base() { }
#endif
But I guess the proper way would be to use something like mockcpp
Edit: Since your are using gtest you might prefer using Google Mock to mock base with a constructor throwing bad_alloc instead of the dirty substitution of base::base

Initializing object which throws exceptions

I have class A, which has constructor A(string filepath)
class A {
public:
A(string filePath);
private:
A();
}
I need to initialize A, and use it later. Constructor A throws exceptions.
int main() {
A a;
try {
a = A("./my/file/path");
} catch (exception e) {
return 1;
}
// Use a
return 0;
}
What would be the most elegant solution? (I dont want to have something like init function, because it makes it possible to have empty A object.)
The most elegant solution is probably to move all your logic which uses a into a function
int use_a(A &a);
int main() {
try {
A a("./my/file/path");
// if we reach here, no exception was thrown
// hence a is safe to use
return use_a(a);
} catch (exception e) {
// if we reach here a never really existed
return 1;
}
}
You're correct to prefer avoiding two-phase initialization - this way use_a can implicitly rely on a being safe to use.
The most elegant solution is:
int main() {
try {
A a("...");
// use a
} catch (const std::exception& e) {
// log e
return 1;
}
return 0;
}
If you don't want empty A objects consider deleting the default constructor. Note that this makes using some stl containers more difficult, while ensuring no invalid object exists.
In addition to that i think using throw in constructors very much allowed. If you don't want to do that consider the noexcept keyword. Note that throws in destructors can cause problems and are usually avoided.
As alternative, you might turn the exception in "optional/checkable" construction with std::optional or std::unique_ptr:
std::optional<A> MakeA(const std::filesystem::path& path)
{
try {
return A{path};
} catch (std::exception& e) {
return std::nullopt;
}
}
int main() {
auto a = MakeA("./my/file/path");
if (!a) {
return 1;
}
// Use *a
return 0;
}

How to catch a constructor exception?

I have a C++ class which throws an exception from the constructor on failure. How can I allocate a local instance of this class (without using new) and handle any possible exceptions, while keeping the try block scope as small as possible?
Essentially, I am looking for the C++ equivalent of the following Java idiom:
boolean foo() {
Bar x;
try {
x = new Bar();
} catch (Exception e) {
return false;
}
x.doSomething();
return true;
}
I do not want to catch exceptions from x.doSomething(), only the constructor.
I suppose what I'm looking for is a way to separate the declaration and the initialization of x.
Is it possible to accomplish this without using heap allocations and pointers?
You can use std::optional from C++17:
bool foo() {
std::optional<Bar> x; // x contains nothing; no Bar constructed
try {
x.emplace(); // construct Bar (via default constructor)
} catch (const Exception& e) {
return false;
}
x->doSomething(); // call Bar::doSomething() via x (also (*x).doSomething() )
return true;
}
This Java idiom doesn't translate well to C++ since Bar x; will require default constructor even if your real constructor requires arguments to be passed.
I'd advise fighting the language to this degree - widening the try block is sufficient - but if you really want to narrow then you could use a function and rely on return value optimisation to obviate a value copy:
Bar foobar()
{
try {
return Bar();
} catch (Exception& e){
/* Do something here like throwing a specific construction exception
which you intercept at the call site.*/
}
}
But really, you could throw a specific exception on construction, so obviating this function approach entirely.
Yes it's possible, if you put all the code in the try clause, for example by using a function try block (to avoid unnecessary nesting and scoping):
bool foo() try
{
Bar x;
x.doSomething();
return true;
}
catch (std::exception const& e)
{
return false;
}
Or in the try clause call another function which does the real work:
void real_foo()
{
Bar x;
x.doSomething();
}
bool foo() try
{
real_foo();
return true;
}
catch (std::exception const& e)
{
return false;
}
Note that it's often not a good idea to throw exceptions in a constructor, as that will halt the construction of the object, and its destructor will not be called.
As noted by Holt, this will also catch exceptions from the doSomething call. There are two ways of solving that:
The simple and standard way: Use pointers.
Use two-stage construction: Have a default constructor which can't throw exceptions, then call a special "construct" function that can throw exceptions.
The second way was common before C++ was standardized, and used extensively in code for the Symbian system. It is not common any more since using pointers for this is much more easy and simpler, especially today with good smart pointers available. I really don't recommend the second way in modern C++.
The easiest way is of course to make sure that the constructor can't throw exceptions at all, or if any is thrown then they are of the nature that the program can't continue anyway and have the program be terminated. As noted in the comments to your question, exceptions in C++ are expensive, and then we also have the abandoned construction issue, and in all using exceptions in C++ should only be done in exceptional cases. C++ is not Java, you should not treat it as such even if there are similar constructs in both languages.
If you still want to throw exceptions from the constructor there is actually a third way to catch only those: Use one of the code-example up top, and throw only specific exceptions that doSomething can never throw and then catch these specific constructors only.
Normally if you want to avoid heap allocations, you can't separate the declaration of a local variable from its definition. So if you were to combine everything in a single function, you would have to do surround the entire scope of x with try/catch block:
boolean foo() {
try {
Bar x;
x.doSomething();
} catch (Exception e) {
return false;
}
return true;
}
No. From your java example, you will have to choose between these 2 possibilities:
Without pointers:
bool foo() {
try {
Bar x;
x.doSomething();
} catch (Exception e) {
return false;
}
return true;
}
With pointers:
bool foo() {
Bar* x = nullptr;
try {
x = new Bar();
} catch (Exception e) {
return false;
}
x->doSomething();
delete x; // don't forget to free memory
return true;
}
Or using managed pointers:
#include <memory>
bool foo() {
std::unique_ptr<Bar> x;
try {
x = new Bar(); // until C++14
x = std::make_unique<Bar>(); // since C++14
} catch (Exception e) {
return false;
}
x->doSomething();
return true;
}
You have to choose between variant of
bool foo() {
std::unique_ptr<Bar> x;
try {
x = std::make_unique<Bar>();
} catch (const BarConstructorException& e) {
return false;
}
x->doSomething();
return true;
}
or
bool foo() {
try {
Bar x;
x.doSomething();
} catch (const BarConstructorException& e) {
return false;
}
return true;
}
In the revised question the OP adds the requirement that
” I do not want to catch exceptions from x.doSomething(), only the constructor [of the local variable].
A simple way to translate the Java code
boolean foo() {
Bar x;
try {
x = new Bar();
} catch (Exception e) {
return false;
}
x.doSomething();
return true;
}
… to C++, is then to use an Optional_ class (like Barton-Nackmann Fallible, boost::optional or C++17 std::optional)
auto foo()
-> bool
{
Optional_<Bar> xo;
try
{
xo.emplace();
}
catch( ... )
{
return false;
}
Bar& x = *xo;
// Possibly other code here, then:
x.doSomething();
return true;
}
A nice alternative is to refactor that code, like this:
struct Something_failure {};
void do_something( Bar& o )
{
// Possibly other code here, then:
o.doSomething();
}
auto foo()
-> bool
{
try
{
Bar x;
do_something( x );
return true;
}
catch( Something_failure const& )
{
throw;
}
catch( ... )
{}
return false;
}
If you do not like the above approaches then you can always go for a dynamically allocated Bar instance, e.g. using a std::unique_ptr for guaranteed cleanup, which however has the general overhead of a dynamic allocation. In Java most every object is dynamically allocated so that might not seem to be a serious disadvantage. But in C++ most objects are superfast stack-allocated so that a dynamic allocation is a very slow operation compared to ordinary operations, so the possible conceptual simplicity of dynamic allocation must be weighted against that.

Is a macro to catch a set of exceptions at different places fine?

I have a set of functions and need to convert potentially thrown exceptions into
error codes.
To this end I have wrapped the actual calls with try/catch statements:
int f_with_error_codes()
{
try {
f(); // wrapped function call
return E_SUCCESS;
}
catch (error1&) {
return E_ERROR1;
}
catch (error2&) {
return E_ERROR2;
}
}
int g_with_error_codes(int a);
{
try {
G g(a); // wrapped expressions
g.print();
return E_SUCCESS;
}
catch (error1&) {
return E_ERROR1;
}
catch (error2&) {
return E_ERROR2;
}
}
...
These catch statmements repeat themselves. Additionally whenever a new exception
is added a new catch clause has to be added to every call wrapper.
Is a macro like below for replacing the catch statements appropriate?
#define CATCH_ALL_EXCEPTIONS \
catch (error1&) { \
return E_ERROR1; \
} \
catch (error2&) { \
return E_ERROR2; \
}
Which would results in:
int f_with_error_codes()
{
try {
f(); // the wrapped
return E_SUCCESS;
}
CATCH_ALL_EXCEPTIONS
You can use a function instead of a macro like this:
int f_with_error_codes()
{
try {
f(); // wrapped function call
return E_SUCCESS;
}
catch (...) {
return error_code();
}
}
int error_code()
{
try {
throw;
}
catch (error1&) {
return E_ERROR1;
}
catch (error2&) {
return E_ERROR2;
}
}
For your case, you don't need any macro.
Just a simple base class containing virtual function will be sufficient.
class error : public std::exception { // std::exception is your wish
const char* what () throw(); // needed if std::exception is based
virtual int GetValue () const = 0; // <--- This is the core part
}
Now, inherit this class with all the error# classes:
class error1 : public error {
virtual int GetValue () const { return E_ERROR1; } // <--- override
};
// ...
Finally your code is as easy as this:
void f_with_error_codes()
{
try {
f(); // wrapped function call
return E_SUCCESS;
}
catch (error& e) { // <--- base handle
return e.GetValue();
}
}
Don't bother about the cost of virtual function here. Because it's minimal and also exceptions are rare events; a very small cost of virtualness is worth for making your code maintainable and extendable.

Is this way of exceptions handling good practice?

Would you change anything in this code?
class LocalPort {
public:
LocalPort(int portNumber) {
innerPort = new ACMEPort(portNumber);
}
void Open() {
try {
innerPort->Open();
}
catch (DeviceResponseException& e) {
throw PortDeviceFailure(e);
}
catch (ATM1212UnlockedException& e) {
throw PortDeviceFailure(e);
}
catch (GMXError& e) {
throw PortDeviceFailure(e);
}
}
private:
ACMEPort* innerPort;
};
/////////
try {
LocalPort* port = new LocalPort(12);
port->Open();
}
catch (bad_alloc& e) {
ReportError(e);
logger.Log("Wyjątek alokacji pamięci", e);
delete port;
}
catch (PortDeviceFailure& e) {
ReportError(e);
logger.Log(e.getMessage(), e);
delete port;
}
What I tried to above do was to make code below look and act better.
try {
ACMEPort* port = new ACMEPort(12);
port->Open();
}
catch (bad_alloc& e) {
ReportPortError(e);
logger.Log("Wyjątek alokacji pamięci", e);
delete port;
}
catch (DeviceReponseException& e) {
ReportPortError(e);
logger.Log("Wyjątek odpowiedzi urządzenia", e);
delete port;
}
catch (ATM1212UnlockedException& e) {
ReportPortError(e);
logger.Log("Wyjątek odblokowania", e);
delete port;
}
catch (GMXError& e) {
ReportPortError(e);
logger.Log("Wyjątek odpowiedzi urządzenia");
delete port;
}
catch (...) {
ReportPortError(0);
logger.Log("Wyjątek nieznanego pochodzenia");
delete port;
}
Did I succeed? Is the first better than the second? What do you think?
It seems like you have badly designed exception classes. Why don't you simply add a member-function getMessage to your exception-hierarchy (preferably in the base-class all your exceptions derive from - std::exception provides the method what that returns an error message). This way, you could simply catch all exceptions in one statement, and handle them all in the same way.
class DeviceResponseException : public std::runtime_error {
public:
DeviceResponseException() : std::runtime_error("Some error message") {}
};
class ATM1212UnlockedException : public std::runtime_error {
public:
ATM1212UnlockedException() : std::runtime_error("Some other error message") {}
};
Then in your code, you can do this:
try {
std::auto_ptr<ACMEPort> port(new ACMEPort(12));
port->Open();
}
catch( std::runtime_error & e) {
ReportPortError(e);
logger.Log(e.what(), e);
}
Since your exception-classes all derive from std::runtime_error, this catch-clause catches them all. This is OK, since the handling is the same for all cases. If you have specific exceptions that require special handling, you add additional catch-clauses.
Also, instead of calling delete port in the exception handler, you should use an std::auto_ptr or boost::scoped_ptr or something of the kind. Read about RAII.
Yes, I would:
have one single exception class and thus:
not translate exceptions from one type to another
catch the exceptions much higher up in the code and thus:
not end up writing more exception handling code than real code
and I would not create objects using new, and if I did I'd use smart pointers
Basically, I think you have completely misunderstood how exceptions should be used.
The best single change you could make to your code is to replace:
ACMEPort* port = new ACMEPort(12);
port->Open();
with:
ACMEPort port(12);
port.Open();
and similarly elsewhere - the need for catching exceptions then goes away.
I'd move the exception handlers into the class and let the class handle errors instead of forcing all callers to handle it. This way you can do clean up of the pointer (if you really have to have a pointer for some reason) by checking the result value of Open():
class LocalPort {
public:
LocalPort(int portNumber) {
innerPort = new ACMEPort(portNumber);
}
bool Open() {
try {
innerPort->Open();
return true;
}
catch (DeviceResponseException& e) {
throw PortDeviceFailure(e);
}
catch (ATM1212UnlockedException& e) {
throw PortDeviceFailure(e);
}
catch (GMXError& e) {
throw PortDeviceFailure(e);
}
catch (bad_alloc& e) {
ReportError(e);
logger.Log("Wyjątek alokacji pamięci", e);
}
catch (PortDeviceFailure& e) {
ReportError(e);
logger.Log(e.getMessage(), e);
}
return false;
}
private:
ACMEPort* innerPort;
};
LocalPort* port = new LocalPort(12);
if (!port->Open()) {
delete port;
}