468,738 Members | 1,753 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,738 developers. It's quick & easy.

clean-up code before throwing an exception may also throw

Hello, in my program I have a function (pseudo code):

void start_mysql_service()
{
obtain handle

start mysql service using handle

if start fails close handle and throw an exception containing error
description

else just close handle and return
}

So no matter if the service is successfully started or not, the handle needs
to be closed to prevent leakage. But the function that closes the handle may
also throw. How should I handle that? catch the close-handle-exception in
start_mysql_service()? Right now I don't catch anything in the
start_mysql_service() function so if it fails to start the service it
prepares to throw an exception, that exception never gets thrown if it the
close handle functions throws. I don't want one error hiding another one.
The real code looks like this and it's ugly (and contains some platform
specific material, sorry about that):
void
start_mysql_service()
{
/* May throw an exception. */
SC_HANDLE mysql_service = get_mysql_service_handle();

if(!StartService(mysql_service, 0, NULL))
{
/* May throw an exception and if it does I never get to throw */
/* the exception indicating that StartService() failed. */
close_service_handle(mysql_service);

/* TODO: Obtain more precise cause of error if possible using
GetLastError() and FormatMessage(). */
throw runtime_error("StartService() failed.");
}

/* May throw an exception. */
close_service_handle(mysql_service);
}
Any ideas how to restructure this into nicer-looking code and solving the
problem of one error hiding another one?

/ E
Jul 22 '05 #1
4 1766
Eric Lilja wrote:
Hello, in my program I have a function (pseudo code):

void start_mysql_service()
{
obtain handle

start mysql service using handle

if start fails close handle and throw an exception containing error
description

else just close handle and return
}
So no matter if the service is successfully started or not, the handle needs
to be closed to prevent leakage. But the function that closes the handle may
also throw. How should I handle that? catch the close-handle-exception in
start_mysql_service()? Right now I don't catch anything in the
start_mysql_service() function so if it fails to start the service it
prepares to throw an exception, that exception never gets thrown if it the
close handle functions throws. I don't want one error hiding another one.
The real code looks like this and it's ugly (and contains some platform
specific material, sorry about that):
Use nested try catch blocks
void
start_mysql_service()
{
/* May throw an exception. */
SC_HANDLE mysql_service = get_mysql_service_handle();

if(!StartService(mysql_service, 0, NULL))
{
/* May throw an exception and if it does I never get to throw */
/* the exception indicating that StartService() failed. */ try
{ close_service_handle(mysql_service); }
catch (...)
{
// we don't care about this exception, we want
// to say what that StartService failed, so we
// catch and ignore it.
} // note: this TODO should probably go before the call to
// call to close_service_handle(), so that any error in c_s_h()
// doesn't mask the results from StartService() /* TODO: Obtain more precise cause of error if possible using
GetLastError() and FormatMessage(). */
throw runtime_error("StartService() failed.");
}

/* May throw an exception. */
close_service_handle(mysql_service);
}
Any ideas how to restructure this into nicer-looking code and solving the
problem of one error hiding another one?

/ E


Jul 22 '05 #2

"Eric Lilja" <er*************@yahoo.com> skrev i en meddelelse
news:cr**********@news.island.liu.se...
Hello, in my program I have a function (pseudo code):

void start_mysql_service()
{
obtain handle

start mysql service using handle

if start fails close handle and throw an exception containing error
description

else just close handle and return
}
First off, the handle should be wrapped into a class providing RAII.

Now your code is reduced into this simpler:

class raii_handle
{
public:
//constructor: obtains handle
//destructor: releases handle
};

void start_mysql_service()
{
handle_class hc(); // constructor allocates

start mysql service using handle
}


So no matter if the service is successfully started or not, the handle
needs to be closed to prevent leakage. But the function that closes the
handle may also throw. How should I handle that? catch the
close-handle-exception in start_mysql_service()? Right now I don't catch
anything in the


I do not see why the closing the handle could trigger an exception:
releasing a ressource ought to always be safe. But assuming your statement
is true and the close can't be ignored, i would augment the handle-class to
have a close method:
class raii_handle
{
public:
//constructor: obtains handle
//destructor: releases handle
~raii_handle()
{
try
{
close();
}
catch (...)
{
// either assert or log error - or just plainly ignore it.
// in places where the errorcheck is needed, you can do an
// explicit close
}
}
void close(); // could throw
};

/Peter
Jul 22 '05 #3

"Peter Koch Larsen" <pk*****@mailme.dk> wrote in message
news:F4********************@news000.worldonline.dk ...

"Eric Lilja" <er*************@yahoo.com> skrev i en meddelelse
news:cr**********@news.island.liu.se...
Hello, in my program I have a function (pseudo code):

void start_mysql_service()
{
obtain handle

start mysql service using handle

if start fails close handle and throw an exception containing error
description

else just close handle and return
}
First off, the handle should be wrapped into a class providing RAII.

Now your code is reduced into this simpler:

class raii_handle
{
public:
//constructor: obtains handle
//destructor: releases handle
};

void start_mysql_service()
{
handle_class hc(); // constructor allocates


You mean handle_class hc; I presume. The above declares a function as you
know, a silly typo I've made myself numerous times.

start mysql service using handle
}


So no matter if the service is successfully started or not, the handle
needs to be closed to prevent leakage. But the function that closes the
handle may also throw. How should I handle that? catch the
close-handle-exception in start_mysql_service()? Right now I don't catch
anything in the
I do not see why the closing the handle could trigger an exception:
releasing a ressource ought to always be safe. But assuming your statement
is true and the close can't be ignored, i would augment the handle-class
to have a close method:


Well, it can fail at least and I (the programmer) want to be notified of
such errors so I'm making close_service_handle() throw. I like the idea of
wrapping the handle in a class..it gets more robust because you cannot
forget to close the handle, the destructor will do it for you. But if the
destructor fails to close the handle I want to know somehow..an exception is
not a good idea I guess..I like the logging idea you proposed.

class raii_handle
{
public:
//constructor: obtains handle
//destructor: releases handle
~raii_handle()
{
try
{
close();
}
catch (...)
{
// either assert or log error - or just plainly ignore it.
// in places where the errorcheck is needed, you can do an //
explicit close
}
}
void close(); // could throw
};

/Peter


Thanks for your help

/ Eric
Jul 22 '05 #4

"Eric Lilja" <er*************@yahoo.com> skrev i en meddelelse
news:cr**********@news.island.liu.se...

"Peter Koch Larsen" <pk*****@mailme.dk> wrote in message
news:F4********************@news000.worldonline.dk ...

"Eric Lilja" <er*************@yahoo.com> skrev i en meddelelse
news:cr**********@news.island.liu.se...

[snip]
Now your code is reduced into this simpler:

class raii_handle
{
public:
//constructor: obtains handle
//destructor: releases handle
};

void start_mysql_service()
{
handle_class hc(); // constructor allocates
You mean handle_class hc; I presume. The above declares a function as you
know, a silly typo I've made myself numerous times.


Of course.

[snip]

I do not see why the closing the handle could trigger an exception:
releasing a ressource ought to always be safe. But assuming your
statement is true and the close can't be ignored, i would augment the
handle-class to have a close method:


Well, it can fail at least and I (the programmer) want to be notified of
such errors so I'm making close_service_handle() throw. I like the idea of
> wrapping the handle in a class..it gets more robust because you cannot

forget to close the handle, the destructor will do it for you. But if the
destructor fails to close the handle I want to know somehow..an exception
is not a good idea I guess..I like the logging idea you proposed.


Right. But do examine WHY the call might fail. I've never seen errors of a
type that couldn't either be ignored or replaced by an assertion.
[snip]
Jul 22 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

8 posts views Thread by Craig Thomson | last post: by
7 posts views Thread by Creative Acceleration | last post: by
reply views Thread by John . | last post: by
reply views Thread by Sreejumon[MVP] | last post: by
reply views Thread by Ed J | last post: by
2 posts views Thread by roel.schreurs | last post: by
5 posts views Thread by Rob R. Ainscough | last post: by
reply views Thread by Christopher | last post: by
xarzu
2 posts views Thread by xarzu | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.