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