Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Exception handling problem

Reply
Thread Tools

Exception handling problem

 
 
woodbrian77@gmail.com
Guest
Posts: n/a
 
      07-03-2013
I'm not sure if the following is due to a misunderstanding
on my part or a clang 3.2 problem. Notice the two catch
blocks below.

try{
// ...
}catch(eof const& ex){
syslog(LOG_ERR,"Got end of stream notice: %s",ex.what());
// ...
}catch(::std::exception const& ex){
syslog(LOG_ERR,"Problem handling response %s",ex.what());
// ...
}

In a test I've caused my back tier to close it's connection
to the middle tier every 500th request. The code above is
from the middle tier. I have two definitions of the eof
class:

#if 0
class eof : public failure {

public:
explicit eof (char const* what_) : failure(what_)
{}

~eof () throw()
{}
};

#else

class eof : public ::std::exception {
::std::string whatStr;

public:
explicit eof (char const* what_) : whatStr(what_)
{}

~eof () throw()
{}

char const* what () const throw()
{ return whatStr.c_str(); }

template <class T>
eof& operator<< (T val)
{
::std:stringstream ss;
ss << val;
whatStr.append(ss.str().c_str());
return *this;
}
};

#endif

If I use the second, longer form, an eof exception is
caught as expected. But if I build the middle tier with
the shorter form of eof, the handler for std::exception
is the one used. This code and the definition of failure
is here --
http://webEbenezer.net/misc/ErrorWords.hh

I'd prefer to use the shorter form, but can't at this point.
Thanks in advance.


Brian
Ebenezer Enterprises - In G-d we trust.
http://webEbenezer.net
 
Reply With Quote
 
 
 
 
Ian Collins
Guest
Posts: n/a
 
      07-03-2013
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> I'm not sure if the following is due to a misunderstanding
> on my part or a clang 3.2 problem. Notice the two catch
> blocks below.
>

<snip>
>
> If I use the second, longer form, an eof exception is
> caught as expected. But if I build the middle tier with
> the shorter form of eof, the handler for std::exception
> is the one used. This code and the definition of failure
> is here --
> http://webEbenezer.net/misc/ErrorWords.hh
>
> I'd prefer to use the shorter form, but can't at this point.
> Thanks in advance.


The code looks fine (except for those pesky prepended colons!). Maybe
you have hit a compiler bug. Does the code work as expected with gcc?

--
Ian Collins
 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      07-03-2013
On 7/3/2013 4:33 PM, (E-Mail Removed) wrote:
> I'm not sure if the following is due to a misunderstanding
> on my part or a clang 3.2 problem. Notice the two catch
> blocks below.
> [...]


You're supposed to catch what's thrown. I didn't see the code that
throws. Did you write it? Or does it come from the system?

V
--
I do not respond to top-posted replies, please don't ask
 
Reply With Quote
 
woodbrian77@gmail.com
Guest
Posts: n/a
 
      07-03-2013
On Wednesday, July 3, 2013 8:53:49 PM UTC, Ian Collins wrote:
>
> The code looks fine (except for those pesky prepended colons!). Maybe
> you have hit a compiler bug. Does the code work as expected with gcc?
>


Checking. Using gcc 4.8.0 it behaves the same as clang.
I suppose it's unlikely they are both wrong.

The makefile is here --
http://webEbenezer.net/misc/makefile
..
 
Reply With Quote
 
woodbrian77@gmail.com
Guest
Posts: n/a
 
      07-03-2013
On Wednesday, July 3, 2013 9:18:30 PM UTC, Victor Bazarov wrote:
>
> You're supposed to catch what's thrown. I didn't see the code that
> throws. Did you write it? Or does it come from the system?
>


int cmw::sockRead (sock_type sock, void* data, int len
, sockaddr* fromAddr, socklen_t* fromLen)
{
int rc = recvfrom(sock
, static_cast<char*> (data)
, len
, 0
, fromAddr
, fromLen
);
if (rc < 0) {
auto err = GetError();
if (ECONNRESET == err) {
throw eof("sockRead -- ECONNRESET");
}
throw failure("sockRead -- len: ") << len << " errno: " << err;
} else {
if (rc == 0) {
throw eof("sockRead -- rc == 0. len: ") << len; // <-- this line
}
return rc;
}
}

Sorry. The line with the comment throws. I get the
same message/what string/ either way and I've checked
that that message is only thrown in this one place.

 
Reply With Quote
 
Thomas J. Gritzan
Guest
Posts: n/a
 
      07-03-2013
Am 03.07.2013 23:29, schrieb (E-Mail Removed):
> On Wednesday, July 3, 2013 9:18:30 PM UTC, Victor Bazarov wrote:
>>
>> You're supposed to catch what's thrown. I didn't see the code that
>> throws. Did you write it? Or does it come from the system?
>>

>
> throw eof("sockRead -- rc == 0. len: ") << len; // <-- this line


> Sorry. The line with the comment throws. I get the
> same message/what string/ either way and I've checked
> that that message is only thrown in this one place.


Throwing together a short example with the same problem:

#include <iostream>

struct failure {
failure& self() {
return *this;
}
};
struct eof : failure {};

int main()
{
try {
throw eof().self();
}
catch (eof const&) {
std::cout << "ok!" << std::endl;
}
catch (...) {
std::cout << "problem!" << std::endl;
}
}

You don't throw an /eof/, you throw a /failure/ because operator<<
returns a failure&. This is called slicing.

--
Thomas
 
Reply With Quote
 
woodbrian77@gmail.com
Guest
Posts: n/a
 
      07-03-2013
On Wednesday, July 3, 2013 10:25:35 PM UTC, Thomas J. Gritzan wrote:

> You don't throw an /eof/, you throw a /failure/ because operator<<
> returns a failure&. This is called slicing.
>


That makes sense.

I tried this:

class eof : public failure {

public:
explicit eof (char const* what_) : failure(what_)
{}

~eof () throw()
{}

template <class T>
eof& operator<< (T val)
{
failure:perator<<(val);
return *this;
}
};

And that is working as expected.

 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      07-04-2013
On Wednesday, July 3, 2013 10:29:43 PM UTC+1, (E-Mail Removed) wrote:
> On Wednesday, July 3, 2013 9:18:30 PM UTC, Victor Bazarov wrote:


> > You're supposed to catch what's thrown. I didn't see the code that
> > throws. Did you write it? Or does it come from the system?


> int cmw::sockRead (sock_type sock, void* data, int len
> , sockaddr* fromAddr, socklen_t* fromLen)
> {
> int rc = recvfrom(sock
> , static_cast<char*> (data)
> , len
> , 0
> , fromAddr
> , fromLen
> );
> if (rc < 0) {
> auto err = GetError();
> if (ECONNRESET == err) {
> throw eof("sockRead -- ECONNRESET");
> }
> throw failure("sockRead -- len: ") << len << " errno: " << err;
> } else {
> if (rc == 0) {
> throw eof("sockRead -- rc == 0. len: ") << len; // <-- this line
> }
> return rc;
> }
> }


> Sorry. The line with the comment throws. I get the
> same message/what string/ either way and I've checked
> that that message is only thrown in this one place.


What is the type returned from "eof( ... ) << len"? If the
operator<< is defined in failure, and it returns a failure&,
then what will be thrown is a failure, not an eof. The type
thrown is the *static* type of the expression, by copy (and
thus, with possible slicing). If for some reason, you need to
throw the dynamic type, the solution is to provide a virtual
member function (say raise), and overload that in all of the
derived classes to do the throw there (where the dynamic type
has been resolved). Although in your case, that would lead to
some mighty strange syntax:

(eof( "..." ) << len).raise();

Alternatively, you can use a global function:

raise( eof( "..." ) << len );

which is less awkward.

--
James
 
Reply With Quote
 
woodbrian77@gmail.com
Guest
Posts: n/a
 
      07-04-2013
On Thursday, July 4, 2013 12:19:04 PM UTC-5, James Kanze wrote:
>
> What is the type returned from "eof( ... ) << len"? If the
> operator<< is defined in failure, and it returns a failure&,
> then what will be thrown is a failure, not an eof. The type
> thrown is the *static* type of the expression, by copy (and
> thus, with possible slicing).


Yes, that was the problem.

> If for some reason, you need to
> throw the dynamic type, the solution is to provide a virtual
> member function (say raise), and overload that in all of the
> derived classes to do the throw there (where the dynamic type
> has been resolved). Although in your case, that would lead to
> some mighty strange syntax:
>
> (eof( "..." ) << len).raise();
>
> Alternatively, you can use a global function:
>
>
> raise( eof( "..." ) << len );
>
> which is less awkward.
>


I'm not sure how that would be better than what I
have now -- see my reply to Thomas Gritzan.
 
Reply With Quote
 
Öö Tiib
Guest
Posts: n/a
 
      07-04-2013
On Thursday, 4 July 2013 21:42:20 UTC+3, (E-Mail Removed) wrote:
> On Thursday, July 4, 2013 12:19:04 PM UTC-5, James Kanze wrote:
> > If for some reason, you need to
> > throw the dynamic type, the solution is to provide a virtual
> > member function (say raise), and overload that in all of the
> > derived classes to do the throw there (where the dynamic type
> > has been resolved). Although in your case, that would lead to
> > some mighty strange syntax:
> >
> > (eof( "..." ) << len).raise();
> >
> > Alternatively, you can use a global function:
> >
> >
> > raise( eof( "..." ) << len );
> >
> > which is less awkward.
> >

>
> I'm not sure how that would be better than what I
> have now -- see my reply to Thomas Gritzan.


A reason why a central 'raise' function can be better is debugging. If
exceptions are thrown very rarely then it is rather nice place for a
break point.

A reason why your solution would not pass some reviews is that public
'operator<<' in 'eof' hides public 'operator<<' of base class 'failure'.
That is considered needless complexity by lot of coding standards.
 
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
signal handling and (structured) exception handling Peter C++ 34 10-17-2009 10:03 AM
Exception of type 'System.Web.HttpUnhandledException' wasthrown.Exception has been thrown by the target of an invocation.System.WebSystem.Exception jobs ASP .Net 1 11-16-2007 05:57 PM
while executing my client program i get the exception javax.naming.LinkException: [Root exception is javax.naming.LinkException: [Root exception is javax.naming.NameNotFoundException: remaining if plz anybody know how to solve this problem then mahesh Java 0 03-08-2007 12:26 PM
SoapExtension for Global Exception handling; but prevent exception from propagating!! VSK ASP .Net Web Services 0 07-29-2003 05:39 PM
Exception handling problem Alex ASP .Net 0 07-17-2003 10:56 PM



Advertisments