Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > clean-up code before throwing an exception may also throw

Reply
Thread Tools

clean-up code before throwing an exception may also throw

 
 
Eric Lilja
Guest
Posts: n/a
 
      01-05-2005
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


 
Reply With Quote
 
 
 
 
red floyd
Guest
Posts: n/a
 
      01-05-2005
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
>
>


 
Reply With Quote
 
 
 
 
Peter Koch Larsen
Guest
Posts: n/a
 
      01-05-2005

"Eric Lilja" <> skrev i en meddelelse
news:crhska$82b$...
> 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


 
Reply With Quote
 
Eric Lilja
Guest
Posts: n/a
 
      01-06-2005

"Peter Koch Larsen" <> wrote in message
news:F4%Cd.80603$ ...
>
> "Eric Lilja" <> skrev i en meddelelse
> news:crhska$82b$...
>> 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


 
Reply With Quote
 
Peter Koch Larsen
Guest
Posts: n/a
 
      01-08-2005

"Eric Lilja" <> skrev i en meddelelse
news:crhv7a$8ol$...
>
> "Peter Koch Larsen" <> wrote in message
> news:F4%Cd.80603$ ...
>>
>> "Eric Lilja" <> skrev i en meddelelse
>> news:crhska$82b$...



[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]


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
having "throw" write to a file before actually throwing Jacek Dziedzic C++ 13 03-03-2006 11:06 PM
JNI's throw new does not throw an exception yarona@m-sys.com Java 15 09-08-2005 08:36 AM
Calling function that may throw an exception Eric Lilja C++ 12 11-17-2004 11:59 AM
Overriden method doesn't throw Exception, super may. VisionSet Java 51 07-13-2004 11:28 PM
Throw Exception Vs Throw New Exception Kerri ASP .Net 2 10-27-2003 02:13 PM



Advertisments