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.
This design basically wraps a bunch of flags in a class, adds
redundant boilerplate and reduces exceptions to glorified C-style
error codes and flags. What's the point of using exceptions here
at all if you use if statements and gotos to handle the error
anyway? 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. How would you even know to
define if a networking error is transient or not?
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. instead, we need to see how we can improve and
refine further the already quite successful exceptions design.
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.