On 19-Aug-12 11:04, foobar wrote:
On Wednesday, 15 August 2012 at 19:29:44 UTC, Dmitry Olshansky wrote:
On 12-Aug-12 07:28, Marco Leise wrote:
Am Sun, 12 Aug 2012 05:02:25 +0200
schrieb Marco Leise <marco.le...@gmx.de>:

---D->>

/**
 * Receives a response from the server.
 *
 * Some explanation of what
 * the function does in detail.
 *
 * Params:
 *    response = receives the whole response
 * Throws:
 *    UnexpectedResponseException if the server sent us garbage
 *
 *    UnauthenticatedException we need retry after we have logged in
 *
 *    SecurityException we have to switch to a secure connection for
this
 *
 *    DisconnectException the connection was unexpectedly terminated
 * Returns: the associated response code
 */
int foo(out string response)
{...}

<<-D---

could become:

---D->>

/**
 * Receives a response from the server.
 *
 * Some explanation of what
 * the function does in detail.
 *
 * Params:
 *    response = receives the whole response
 * Returns: the associated response code
 */
int foo(out string response) throws
    UnexpectedResponseException, /// if the server sent us garbage
    UnauthenticatedException, /// we need retry after we have logged in
    SecurityException, /// we have to switch to a secure connection
for this
    DisconnectException /// the connection was unexpectedly terminated
{...}

<<-D--


When I see code like this I have one single thought - error codes!

Indeed that's what is used in this example, with Exceptions only being
convenient (and separate) transport for error codes. So the net
progress is creating 1:1 type for each error condition (start counting
the lines of code) and then...

If I got it right somewhere later foo is supposed to be used like this:
try{
...some_code
foo();
...other code
}
catch(UnexpectedResponseException)
{
    print error and disconnect this server or retry?
}
catch(UnauthenticatedException)
{
    print error 2
}
catch(SecurityException)
{
    sslFoo(resp); // this one is just awesome ;)
}
catch(DisconnectException )
{
    print error 3 & (ask to) reconnect?
}

Or used a catch all and do type switch Java-style to see if Exception
is one of interesting to you types.  Needless to say awful again.

First SecurityError is gross fiction as you either know to
authenticate (need credentials in the interface) or do auto detection
(like try HTTPS, then fallback to HTTP).

Moreover encoding _cause_ of error in type is useless, end user needs
a hint on the proper way to handle error. It's like pointing out a guy
who made the mistake and how stupid it is instead of proposing the
ways to fix the situation.

what I'd expect the code to be is (been discussed before):
class NetworkException
{
    @property bool transient; // packet lost or whatever, can re-try
with the same parameters
    @property bool lost; // need reconnect to restore, server down or
disconnected or unexpected input
    @property string msg();
}

This reduces all the handling to:
catch(NetworkException ne)
{
    if(ne.lost)
        //ya kill me, but you got the idea ;)
        goto ReconnectAndRetry;
    if(ne.transient){
        warning("..."); //log failure
        goto RetryAndCheckTryCount;
    }
    error(ne.msg);
}

Including but not limited to the time when foo's author adds more
types to his "throws list". Unlike checked exceptions it won't break
build just for the fuck of it *and* it will still work correctly.

In fact if we manage to come up with proper reasonable standard
exceptions like Network/IO/etc. that everybody derives from error
handling would become damn easy with *any* library.

IMHO, the suggested NetworkException is a bad design as it weakens one
of the goals of exceptions - to document the programmer's intent.

I've never seen this goal. "document programmer intent?" could you expand on this?


This design basically wraps a bunch of flags in a class,
This example does show how common flags could be more useful then a bunch of names. Flags in fact are fast way to do sets...

adds redundant
boilerplate
Compared to what?

 and reduces exceptions to glorified C-style error codes and
flags.

They are already glorified C-style error codes in Java. And that's something I tried to improve on (see the thread) Obviously the "and flags" is all I get ;)

What's the point of using exceptions here at all if you use if
statements and gotos to handle the error anyway?

These goto's are conceptual, I don't write the entrie program for the sake of brevity. And the point of exceptions is not to use rows of catch instead of rows of ifs.

Seems redundant to me.
Moreover, I don't agree with encoding the action or even just a hint in
the exception. It goes against common logic - the code that generates
the error *cannot* know what should be done to handle it - after all if
it does know it would handle the error itself.

Right it doesn't know the cure-it-all action or it would have done it on its own, I told so in my posts. Also keep in mind that low-level code may know how to handle errors but doing it is not always acceptable or possible at this level. So it passes info up
to somewhere above to take the correct action _based_ on information.

 How would you even know
to define if a networking error is transient or not?
If it's worth retying later.
It's a question of can or cannot be. Hetwork unreachable is pretty much not transient. Resolving host failed - can be a minor glitch. The fact that connection broke also useful to know, so that handler can safe reconnect (if handler thinks it feasible, low-level code can't decide here).


I agree that there are some issues with the common java style design of
exceptions. That does not mean we need to go back to ifs and gotos.

First stop riding on gotos, they are long and tired concept. And my design doesn't implies using them, I've put them in example as conceptual handlers instead of writing ...handle condition x...

ifs in no way worse then catches on their own. The whole point was - doing tons of error classes is indeed spawning glorified error codes. Bundling together names is in no way better then proving a flag that indicates these bundles.

instead, we need to see how we can improve and refine further the
already quite successful exceptions design.

I'd suggest that. In case you missed the design doesn't change a thing in language. It even doesn't change the code that already works. It suggest a specific standard hierarchy that helps unifying error handling. That is something to discover.

One improvement that can be done is something like Nemerle's - Nemerle
has pattern matching in the language and the catch clause uses that same
mechanism.

So you match any of 10 exceptions in one catch. How do you work with resulting object? Examples please. What benefit it has compared to matching 1 sub-root exception type with the field that indicates common information of interest of these 10 exceptions.



--
Olshansky Dmitry

Reply via email to