View mode: basic / threaded / horizontal-split · Log in · Help
August 17, 2012
Re: Exception programming difficult
Am Thu, 16 Aug 2012 15:11:41 +0200
schrieb "Manipulator" <volcz@kth.se>:

> I had times when I missed the Java-style Exception handling.
> 
> First time I just the D sockets exceptions was thrown during 
> runtime. The Library Reference didn't tell my anything about 
> exceptions neither did the compiler.
> This could've been avoided with documentation stating which 
> exceptions can be thrown or if the compiler had warned me about 
> it.
> I see checked exception handling as mean to remind programmers to 
> handle certain errors. This is not done in D.
> 
> I've also cursed the Java-style many times. For example:
> interface MyInterface {
>   public void method throws IOException();
> }
> 
> class MyClass implements MyInterface {
>   public void method throws IOException() {
>    //Doesn't need throw IOException!!!!
>   }
> }
> 
> I liked the idea when the compiler is able to warn me about 
> unhandled exceptions.
> 

I've been thinking shortly about this. Can we narrow down the thrown exceptions? Can an interface declare that it's descendants may throw IOExceptions, but an implementation may practically be nothrow?
This could have the special effect that in cases where MyClass is used as the declared type, no exception handling would have to be done, while that would still be the case for MyInterface. If that's possible it would be another small improvement over Java.

-- 
Marco
August 17, 2012
Re: Possible "throws" syntax
On 17-Aug-12 11:47, Marco Leise wrote:
[snip]

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

> Just for the fuck of it, huh :) ?

I'm currently working on Java project part-time (it shows :) ), a small 
app-specific server that has to pipeline work items back and forth and 
do it fast. It's damn frustrating to see (and adapt) when your colleges 
add/remove exception specs of their interface. And even I discover that 
methods get or lose throws ExceptionX frequently during development.

> Interesting read, do you know an example, probably a standard library of some other language,
that offers standard exceptions like this?

No, but it's about time to innovate. What I know for sure is that other 
failed to deliver. (C++ STL - failed, Java - see above, .NET appears to 
be in the same boat - i.e. more exceptions good and any)

> If I understand you correctly, the idea is to not use
distinct error ids (be they codes or exception classes), but a mix of 
flags.

While I think flags would be a very common way to _hint_ on how to 
correct the error (or current state of system as a whole). I do suspect 
that some error types may need more then just a flag, but who knows.

So you'd have pretty much one "catch" with a few "if"s,
but with the flags you can decide on the granularity.

Something like that. With ifs you query important properties about error 
that allow you to pick the best recover decision. The whole propose of 
flags is to unify only _important_ items for the _decision_ process and 
hide useless variability (it still goes to message).

A comic-book example:
Top scientist breaks into Mr. President room and cries:
"We are doomed! Crystal oculator was miscalculated, all readings are 
under 0.6543124312,  helerium core just melted!"

Now does it mean it's time to evacuate promptly or instead give order to 
isolate the secret lab and "end" this guy's project? Unless Mr.President 
has a nice and long lookup table of all (pseudo) scientific terms he has 
no clue.


-- 
Olshansky Dmitry
August 17, 2012
Re: Exception programming difficult
Am Mon, 13 Aug 2012 19:32:38 +0400
schrieb Dmitry Olshansky <dmitry.olsh@gmail.com>:

> I think the true cryptonite that melts "checked exceptions" to a pile of 
> green goo is templated code:
> 
> So (*yawn*) tell what kind of exception specification the following 
> function should have:
> 
> auto joiner(RoR, Separator)(RoR r, Separator sep);
> 
> How would you guarantee upfront what kind of exceptions it can throw is 
> beyond me. It all depends on code that you can't reach or know by the 
> very definition of template.

At first I thought the very definition of template doesn't do much in terms of nothrow inference, so what. But I made it to easy on myself, so I'll go into details a bit.
When the template is instantiated and it has no @throws annotations, it would infer the thrown exceptions in the fashion nothrow is inferred.
If you add nothrow/@throws to a surrounding function that uses this instantiation, then you get into the situation that you really don't know upfront what is thrown until you do a test compile.

I could blame it on the compile time duck typing, that evades declared thrown exceptions. It seems that exceptions just don't work with templates [that call arbitrary functions passed to them through struct/class parameters]. In general it is not possible to reason about the thrown exceptions in templated code, unless everything is marked nothrow or the code is simple, like chains of filter, map, reduce, ….
Currently you cannot use joiner in nothrow functions and I have no idea which exception you are supposed to catch.

This is a whole different topic and for the sake of this proposal I'd like to go with not documenting these exceptions introduced from the outside, but making them aware to the programmer whenever he/she uses @throws on functions using such templates.

-- 
Marco
August 17, 2012
Re: Possible "throws" syntax
Am Fri, 17 Aug 2012 12:48:01 +0400
schrieb Dmitry Olshansky <dmitry.olsh@gmail.com>:
> […]
> Something like that. With ifs you query important properties about error 
> that allow you to pick the best recover decision. The whole propose of 
> flags is to unify only _important_ items for the _decision_ process and 
> hide useless variability (it still goes to message).
> 
> A comic-book example:
> Top scientist breaks into Mr. President room and cries:
> "We are doomed! Crystal oculator was miscalculated, all readings are 
> under 0.6543124312,  helerium core just melted!"
> 
> Now does it mean it's time to evacuate promptly or instead give order to 
> isolate the secret lab and "end" this guy's project? Unless Mr.President 
> has a nice and long lookup table of all (pseudo) scientific terms he has 
> no clue.

I experimented with an enum that combines some error codes into a common action, like "retry later", "authenticate", "give up", the list goes on. But for the networking case (and that's why I was asking for an example of a broader application) it is actually nice to have exceptions that read like an FAQ: Am I still connected? Is the error temporary?

Now to the president: He might have a technical advisor, that translates the scientists explanation. Assume I'd implement an NNTP client. The protocol allows for sudden state changes by the server, that would cause unexpected errors. (Reconfiguration of a running server.) It also allows for extensions, that aside from some formalities can add functionality and error codes.
The president would be a programmer who is only interested in simple way to read or post in newsgroups with the library hiding all the minutiae of different error codes, detecting supported protocol versions or restoring state on a reconnect (like which newsgroup was selected).
The technical advisor may want to make use of an extension for authentication or searching the newsgroup, so he needs to get at all the information and also create raw requests with custom error handling. I think WebDAV is one such extension of HTTP.

-- 
Marco
August 17, 2012
Re: Possible "throws" syntax
On 17-Aug-12 14:10, Marco Leise wrote:
> Am Fri, 17 Aug 2012 12:48:01 +0400
> schrieb Dmitry Olshansky <dmitry.olsh@gmail.com>:
>> […]
>> Something like that. With ifs you query important properties about error
>> that allow you to pick the best recover decision. The whole propose of
>> flags is to unify only _important_ items for the _decision_ process and
>> hide useless variability (it still goes to message).
>>
>> A comic-book example:
>> Top scientist breaks into Mr. President room and cries:
>> "We are doomed! Crystal oculator was miscalculated, all readings are
>> under 0.6543124312,  helerium core just melted!"
>>
>> Now does it mean it's time to evacuate promptly or instead give order to
>> isolate the secret lab and "end" this guy's project? Unless Mr.President
>> has a nice and long lookup table of all (pseudo) scientific terms he has
>> no clue.
>
> I experimented with an enum that combines some error codes into a common action, like "retry later", "authenticate", "give up", the list goes on.
Don't try to combine the _action_ into Exception. If there is definitive 
action encoded (like re-try) then just do it. If there is uncertainty of 
what exactly needs to be re-done (failure somewhere deeply nested) then 
provide a hint on "state/possible recovery".
But for the networking case (and that's why I was asking for an example 
of a broader application)
it is actually nice to have exceptions that read like an FAQ: Am I still 
connected? Is the error temporary?

That's what I have shown (see transient & lost). Again  exception 
doesn't know _how_ (no action or it would do it itself) to restore, it 
just provides nice hints to decision maker that indeed read as FAQ.
>
> Now to the president: He might have a technical advisor, that translates the scientists explanation.
 Assume I'd implement an NNTP client.
The protocol allows for sudden state changes by the server, that would 
cause unexpected errors.
(Reconfiguration of a running server.)
Should be part of library's job (technicians of said scientist).

It also allows for extensions,
that aside from some formalities can add functionality and error codes.
> The president would be a programmer who is only interested in simple way to read or post in newsgroups with the library hiding all the minutiae of different error codes, detecting supported protocol versions or restoring state on a reconnect (like which newsgroup was selected).
> The technical advisor may want to make use of an extension for authentication or searching the newsgroup,
so he needs to get at all the information and also create raw requests 
with custom error handling.
First of all there are convenience wrappers and there is low-level API. 
My proposition doesn't hurt this separation at all.

And here is where inheritance finally plays it's role.
The thing does nest:
NNTPException : NetworkExcpetion (lost, transient)

NNTPException contains more interesting & specific info (maybe even 
straight error codes - why not if they are well documented?)

So high-level API is constructed from low-level, and it has some simple 
hardwired logic but by the end of day it just passes through most 
unexpected exceptions.

So president type of programmer just looks at it as NetworkException 
(as he should, the higher you sit the less you see) and checks easy 
flags/fields to make global recovery action.

The technical savvy type of programmer can use low-level API directly 
and even catch NNTP exceptions if RFC error codes are needed (and there 
could be genuine Network errors like connection lost).

>I think WebDAV is one such extension of HTTP.

I way incompetent with NNTP. So take the above with a grain of salt.

P.S. For some reason Thunderbird flats your paragraphs into a very long 
lines, split by hand sorry if inaccurate ;).

-- 
Olshansky Dmitry
August 18, 2012
Re: Exception programming difficult
On Thursday, 16 August 2012 at 10:37:01 UTC, Kagamin wrote:
> On Wednesday, 15 August 2012 at 17:44:14 UTC, SomeDude wrote:
>> Or you could have told him HOW he messed up. By just throwing 
>> an Exception, you are not helpful at all, you are just telling 
>> that he is an ass and that he will be punished for that. Or 
>> maybe he will curse you thinking that your program doesn't 
>> work.
>>
>> Let's say I write a FileParser class  which will read a table 
>> of doubles in a file. I use a number of methods defined in the 
>> JDK like say Double.parse(String) which throws a 
>> NumberFormatException("on line" + lineNumber), and catching 
>> that exception, I am able to tell the user that one of the 
>> numbers on line lineNumber is badly formatted, instead of just 
>> telling him that reading the file with 200,000 lines crashed 
>> the program.
>
> How checked exceptions would help you decide whether line 
> number should be included in the error message?
>
You didn't get my point because it was badly formulated. I wanted 
to emphasize here that because the exception is typed, you can 
give a better information on what is wrong (here a bad 
formatting, and you throw in the line number). The interface of 
Double.parse()  *forces* you to catch that exception, and that is 
a *good* thing. If it didn't force you to catch it, you would 
lazily 1) not catch and let the program crash 2) catch an 
Exception and not be able to tell the user what's the root cause 
of the error, leaving him scratching his head and thinking that 
your program is actually at fault (because it failed) and not the 
file.
So in a sense, Double.parse(), by throwing a 
NumberFormatException, forces you to be precise in your error 
handling and to think about it, i.e answer the questions:
a) must I handle the exception or pass it to another level where 
it makes sense to handle it
b) how can I provide the best information as to how to handle the 
situation.

Just placing a catch all Exception at the top level is obviously 
not enough, because all it says is "something went wrong". It 
doesn't help handling the error at the right place, in the 
correct manner.

It's a misconception that is all too common in the C++ world 
because in C++, exceptions are so crippled that they are 
basically unusable, so people resort to the catch all trick, 
which is most often less than useless.

>> If I catch an IOException as well, I can inform him that the 
>> file is unreadable instead (but that the formatting was not 
>> yet in cause). But if I catch a FileNotFoundException first 
>> (which derives from IOException), I can be more helpful by 
>> informing him/her that the filename passed to the program is 
>> wrong.
>
> How checked exceptions would help you design exception 
> hierarchy? What's your point?

The exception hierarchy helps choosing the right level of 
"graininess" in error handling depending on how you want the user 
to handle errors. You may want to help him establish a diagnosis, 
in which case you will throw the most discriminating exceptions, 
or you may just want to inform him that something went wrong, in 
which case you will rather throw a root exception class. This is 
very similar to the choice you make when writing logs and choose 
their log level. Because checked exceptions force you to catch 
them, you can catch exceptions high in the hierarchy in order to 
avoid catching every single leaf, which is the case if you are 
not interested in handling all these different cases.
August 19, 2012
Re: Possible "throws" syntax
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@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.
August 19, 2012
Re: Possible "throws" syntax
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@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
Next ›   Last »
1 2 3 4 5
Top | Discussion index | About this forum | D home