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.

--
Olshansky Dmitry

Reply via email to