I've got this constructor which throws an exception
GenericSocket::GenericSocket(const string& hostname,
const string& servname):
_hostname(hostname),
_servname(servname)
{
initHints();
int rv;
if((rv = getaddrinfo(_hostname.c_str(),
_servname.c_str(),
&_hints,
&_servinfo)) != 0) {
throw GenericSocketException();
}
}
initHints() does a memset of _hints and sets some variables.
I test it with the google test framework like this:
TEST(CreateObject2, getaddrinfoException)
{
mgs_addrinfo_return = 1;
ASSERT_THROW(new GenericSocket("testhost", "4242"), GenericSocketException);
}
The test fails with a core dump:
[ RUN ] CreateObject2.getaddrinfoException
socket creation failed
terminate called after throwing an instance of 'common::GenericSocketException'
what(): Socket creation failed
[1] 43360 abort (core dumped) ./bin/test_common
Besides the fact that I dont know exactly what goes wrong, I suspect some uninitialised object gets deleted(?), a lot seems to happen under the hood, so I started to wonder if it is good practice to throw an exception in a constructor. Is it maybe better to put this functionality in another function which I can call after the creation of the object, and handle the exception afterwards?
IMHO, throwing an exception in a constructor is the best way to handle a situation like this - do you really want a usable object if there is no socket? it doesn't make sense to me. If it's failing to resolve that address, there's a reason for that and that is worthy of an exception (as long as you handle it correctly!)
In your particular case, you should test the return value and make the exception more useful... (for example, HostNotFound
- which I'd guess is the case here)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With