Possible "throws" syntax

Dmitry Olshansky dmitry.olsh at gmail.com
Sun Aug 19 03:01:54 PDT 2012


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

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


More information about the Digitalmars-d mailing list