Possible "throws" syntax

foobar foo at bar.com
Sun Aug 19 00:04:46 PDT 2012


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.Leise at 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.



More information about the Digitalmars-d mailing list