Return-Path: Delivered-To: apmail-commons-dev-archive@www.apache.org Received: (qmail 7878 invoked from network); 7 Jul 2010 14:14:49 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 7 Jul 2010 14:14:49 -0000 Received: (qmail 95648 invoked by uid 500); 7 Jul 2010 14:14:49 -0000 Delivered-To: apmail-commons-dev-archive@commons.apache.org Received: (qmail 95112 invoked by uid 500); 7 Jul 2010 14:14:47 -0000 Mailing-List: contact dev-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "Commons Developers List" Delivered-To: mailing list dev@commons.apache.org Received: (qmail 95104 invoked by uid 99); 7 Jul 2010 14:14:46 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 07 Jul 2010 14:14:46 +0000 X-ASF-Spam-Status: No, hits=-0.7 required=10.0 tests=RCVD_IN_DNSWL_LOW,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (nike.apache.org: local policy) Received: from [193.74.71.27] (HELO eir.is.scarlet.be) (193.74.71.27) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 07 Jul 2010 14:14:39 +0000 Received: from mail.harfang.homelinux.org (ip-62-235-228-53.dsl.scarlet.be [62.235.228.53]) by eir.is.scarlet.be (8.14.2/8.14.2) with ESMTP id o67EE7pV025128 for ; Wed, 7 Jul 2010 16:14:07 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=scarlet.be; s=scarlet; t=1278512048; bh=Y1NtawEKeK1Q6PplcNwcV1Hw62ZEwY5BpQkWeE+lB0s=; h=Date:From:To:Subject:Message-ID:References:MIME-Version: Content-Type:In-Reply-To; b=O+wEzTMIJ/So/k1cMrUk/ItHPU5eNh8zB1BOJoqT8+H1/R1jFIyAqMjo1ajADen1r YzTAahzAhi3XEiA2tY/2W5kONFFarWGDH/Meb1uWSa6LUxDD4LF/NQJtspqomNK1Oa pTQjF3DJEPSipIusoYW19DyWD6iyAEU0Zc07DGb4= Received: from localhost (mail.harfang.homelinux.org [192.168.20.11]) by mail.harfang.homelinux.org (Postfix) with ESMTP id 553C3617BA for ; Wed, 7 Jul 2010 15:56:41 +0200 (CEST) Received: from mail.harfang.homelinux.org ([192.168.20.11]) by localhost (mail.harfang.homelinux.org [192.168.20.11]) (amavisd-new, port 10024) with ESMTP id vd8W71d0UnHh for ; Wed, 7 Jul 2010 15:56:38 +0200 (CEST) Received: from dusk.harfang.homelinux.org (mail.harfang.homelinux.org [192.168.20.11]) by mail.harfang.homelinux.org (Postfix) with ESMTP id E550A617AD for ; Wed, 7 Jul 2010 15:56:38 +0200 (CEST) Received: from eran by dusk.harfang.homelinux.org with local (Exim 4.71) (envelope-from ) id 1OWV78-0005J6-HD for dev@commons.apache.org; Wed, 07 Jul 2010 15:56:38 +0200 Date: Wed, 7 Jul 2010 15:56:37 +0200 From: Gilles Sadowski To: dev@commons.apache.org Subject: Re: svn commit: r960602 - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math/analysis/interpolation/ main/java/org/apache/commons/math/exception/ main/java/org/apache/commons/math/util/ main/resources/META-INF/localization/ site/xdoc/ tes... Message-ID: <20100707135637.GD28835@dusk.harfang.homelinux.org> Mail-Followup-To: dev@commons.apache.org References: <20100705141011.CAF1023889E1@eris.apache.org> <4C31FBBD.8060302@gmail.com> <20100705223146.GL6681@dusk.harfang.homelinux.org> <4C327EEA.9080304@gmail.com> <4C32DE2C.6070702@free.fr> <20100706092049.GA28835@dusk.harfang.homelinux.org> <4C331C63.1020606@free.fr> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <4C331C63.1020606@free.fr> X-Operating-System: Tiny Tux X-PGP-Key-Fingerprint: 53B9 972E C2E6 B93C BEAD 7092 09E6 AF46 51D0 5641 User-Agent: Mutt/1.5.20 (2009-06-14) X-DCC-scarlet.be-Metrics: eir 20001; Body=1 Fuz1=1 Fuz2=1 X-Virus-Checked: Checked by ClamAV on apache.org > > And I disagree with both your disagreements. Could you _please_ answer all > > the drawbacks of your approach in several scenarios which I've put forward > > many times already, instead of always only cling to the one use-case which > > you are interested in? Still no answer on this... > > Please! What kind of ?@#! application is it that you take as an example, > > that will print a terse message and exit? The _least_ a program should > > do when it bails out is print the stack trace! > > I am thinking about the programs I use: space flight dynamics programs > that do things like orbit propagation, operational events forecasts > (eclipse entry/exit, visibility from ground station, apogee/perigee/node > crossings, South Atlantic Anomaly entry/exit, thrusters firings, > Sun/Moon/stars visibility/dazzling in optical sensors ...), orbit > determination, maneuver optimization, space debris close approaches and > avoidance ... > > These applications are often integrated into a large framework (a > satellite control enter). They provide graphical user interface. The > errors are often displayed in limited dedicated places (error message > line at the bottom of some windows, popup window with one or two text > lines, and most of the time a single line of text transmitted to a > centralized log application gathering messages from the whole control enter. > > Another example are web applications. The interactive part runs on a > browser and the core engine runs on the server. The messaging protocol > between the two doesn't provided anything but a string to display error > messages, and the UI is often designed for one line strings, not 50 > lines stack traces. > > A third example are applications running on limited mobile devices like > phones. The display is very limited, it would not handle a stack trace. The problem is not the possible limitation of the interface with the final user: an error that originates in CM should not propagate to the final user! For example (selecting at random from the impressive list of applications above), if some operator pushes a button named "Debris avoidance" and sees "The number of points is less than 2" on his one-line console log. How useful is it? I'm talking about precondition violations here. If they happen, they must be caught by the application and an appropriate error should be generated that is related to the user action that triggered the problem. This is exactly the confusion I was referring to: Only you, as a veteran CM developer, might recognize your "detailed" message string. For a real final user it is no more useful than "Argument was less than 2". [If CM is really intended to display everything to the top-level, then I revise my position, there are far too few error message strings: There should be a specific one for each place where an exception is thrown, explaining in a detailed message why the error occurred at that place in the code... (Just kidding.)] Even if it were so, what you'd have achieved is to pinpoint where the exception was thrown, without the help of the stack trace. But you are still nowhere close to fixing the bug because, without the stack trace, you don't know what action really triggered the exception (a bug in CM, or in the application, or bad usage from the operator?). > > Please! Read chapter 8 of Bloch's Effective Java (less then 20 pages) to see > > that indeed the error message must be reported by the user/operator to the > > developer. This is not debugging. > > The problem we discuss is not related to Java, it is all about > ergonomics. The rules about error messages are consistent everywhere I > looked: they should be user oriented, helpful and must not rely on > program implementation details. When I read: > "provide user-centered wording in messages (e.g. "there was a problem > in copying the file to your disk" rather than "execution error 159")" > in , I > consider it also rules out stack traces. Confusion of responsibilities (continued)... CM is not an end-user application; it is a low-level component. [CM directly communicating with the end-user can also be viewed as breakind encapsulation...] > Of course, Phil you and I can deal with stack traces. In fact, I think > all people on this list (a "dev" list) can and do this all the time. But > users may not. [...] I can agree that stack trace is not for users, though not because it is deemed too complicated, but because if the stack trace appears, it often means that, somewhere in the development chain, someone has not been careful enough. > You consider our users are developers (I think you wrote > it some days ago) and we are not concerned by the users of our users. > However, since at the same time you ask for going to unchecked exception > which will obviously lead to our messages leaking to the higher level > and to final user, I cannot agree with both points at the same time. You misunderstood me. I said that the application developer will have the choice to recover from unchecked exceptions just the same as with checked exceptions. The advantage of unchecked exceptions is that they will relieve CM-users who have no way to handle the problem (i.e. choice vs obligation). And I also said that _none_ of the CM exceptions should ever reach final users (hence my wondering of the necessity of localization inside the CM library). A well-behaved application will want to avoid being crashed by an uncaught exception; at some point, it should catch all "RuntimeException"s and signal to the user that something went terribly wrong with the current action, because an unchecked exception could not be handled. If the programming problem is to be solved, the application should log enough information; a single line will not do. A user who cannot deal with a stack trace should, even more so, never see a CM message that relates to a method called many levels down his own action. In the same way that his action passes through many layers before calling a CM algorithm, then the result (or failure) of this algorithm must be conveyed back in a manner that he can relate to. > If all messages should be tracked and handled by intermediate code, and > if they are only meant to developers with their accompanying stack > trace, then they must be checked exception to be sure no error is > missed. It was probably the Java designer's dream that checked exceptions were the ultimate solution to the error handling problem. But their overuse proved to be a burden; burden that is dealt with in various ways such as, namely, * exception swallowing, or * every method declared to throw "Exception" (i.e. transferring the burden to the caller) etc. Whereas it is so simple not to miss anything: public static void main(String[] args) { // ... try { // ... } catch (RuntimeException e) { LOG.error("Oops, unexpected exception (this is a bug): " + e); } } > If we opt for unchecked exception, there will be leaked messages Which will just prompt for bug-fixes, consisting in not leaking them anymore. > and the stack trace will sometimes not be there (or will be theere for a > user than cannot understand or use them). This look to me similar to > this wonderful analysis of a web server error message: > ; [...] But that's exactly what you want CM to do: Leaking messages that only reflect the inner working of something. As much as this user may not know what he did to get a "Cannot handle request", the user of an application that just displays the CM exception will feel the same way looking at "Number of points is less than 2". I think that you over-estimate the usefulness of the error message string at the expense of making it easier for application programmers to catch the specific exception that they might want to handle. > of course from a > developer or an experienced user, the message is self explanatory, but > consider how it may be misinterpreted by a less experienced user. One of my points, again, is that the exception messages are not meant to convey a thorough explanation, but to indicate that something went wrong. Another point is that at the level of library component the type of the exception object is more important than the String message. Objects make it possible to further customize the behaviour of the upper layers of code. The String is meant for humans to read, and when that has happened it is too late for anything else (the program bailed out). > To me, the trade-off between our diverging points is to: > 1) go to uncheck exceptions wherever possible (your point) > 2) reduce number of difference messages (everybody point) > 3) keep informational messages (both Phil and mine point) > > Items 2 and 3 are sometimes in contradiction and should be applied on a > message by message basis. Please note that I'm not against conveying detailed information. What I've been suggesting is a sound and flexible design. IMO that goal implies: 1. A set of (stateful) exception classes 2. Stringent rules on the use of checked exception 3. Encapsulation of messages localization Now, one of your requirements is that "getMessage" should display a "mini-manual" and, as far as I can see, *that* goal is in contradiction with a significant reduction of the message strings. Moreover, encapsulation (point 3) will then require a huge set of exceptions, most of which will be used only once in the CM code. In order to try and satisfy everyone's requirements (without necessarily reconciling them), I was thinking of introducing a second "Localizable" instance variable in class "MathIllegalArgumentException". This one would not be pattern but a more detailed explanation, that could also be localized. Hence the class "NumberOfPointsIsTooSmallException" would inherit from "NumberIsTooSmallException" and will display "number of points: argument (0) is less than 2" ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Specific context General problem It will not reduce the global number of enums nor make the number of exceptions small but it will at least have the advantage to separate the general problem from the specific context where it occurred. How does that sound? Gilles --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org For additional commands, e-mail: dev-help@commons.apache.org