On 11/10/2013 03:04 PM, Gilles wrote: > On Sun, 10 Nov 2013 10:15:18 +0100, Thomas Neidhart wrote: >> On 11/10/2013 07:03 AM, Phil Steitz wrote: >>> On 11/9/13 3:27 PM, Thomas Neidhart wrote: >>>> On 11/09/2013 11:21 PM, Gilles wrote: >>>>> On Sat, 09 Nov 2013 13:13:05 -0800, Phil Steitz wrote: >>>>>> On 11/5/13 5:21 AM, Gilles wrote: >>>>>>>>>> [...] >>>>>>>>>> I have scanned for exact duplicates quite a few times and never >>>>>>>>>> found any. There are quite a few that are similar, but differ in >>>>>>>>>> material ways (strict versus non-strict inequalities, endpoints >>>>>>>>>> included / not included, etc.). Please do not "collapse" >>>>>>>>>> messages >>>>>>>>>> at the expense of loss of specificity or correctness. >>>>>>>>> FAILED_BRACKETING >>>>>>>>> UNABLE_TO_BRACKET_OPTIMUM_IN_LINE_SEARCH >>>>>>>>> INVALID_BRACKETING_PARAMETERS >>>>>>>> Look at the messages. These are different. They convey different >>>>>>>> information and are appropriate in different contexts. See below. >>>>>>> I've argued that context information should be constructed at the >>>>>>> point where the exception is thrown (where the context is known). >>>>>>> Not all combinations of exceptions and context need be present in >>>>>>> the pattern list. >>>>>>> This is the essence of my proposal below. >>>>>>> >>>>>>>>> My position: the error (failed bracketing) should have its own >>>>>>>>> exception >>>>>>>>> type. The varying contexts could (do not have to) be part of the >>>>>>>>> message >>>>>>>>> built at exception instantiation. >>>>>>>>> >>>>>>>>> If we want to include an indication of location (despite it is >>>>>>>>> already >>>>>>>>> part of the stack trace, so it is _redundant_), we could perhaps >>>>>>>>> add methods >>>>>>>>> to the "ExceptionContext", e.g. "where(LocalizeFormats pattern)" >>>>>>>>> (?). >>>>>>>>> Then, we would have thos patterns in the list: >>>>>>>>> >>>>>>>>> BRACKETING >>>>>>>>> LINE_SEARCH >>>>>>>>> >>>>>>>>> Note: INVALID and FAILED are redundant since the pattern is >>>>>>>>> intended to be >>>>>>>>> included in an exception. >>>>>>>>> >>>>>>>>> >>>>>>>>> A second "interesting" case is >>>>>>>>> >>>>>>>>> INVALID_ROUNDING_METHOD >>>>>>>>> >>>>>>>>> which mixes documentation with error description. Does anyone >>>>>>>>> really thinks >>>>>>>>> that the enumeration of the rounding methods in the error message >>>>>>>>> is necessary >>>>>>>>> or even helpful? >>>>>>>> When I throw an exception, I want to provide an error message that >>>>>>>> is meaningful in the context of the caller, i.e., that someone >>>>>>>> looking at a log or stack trace can make sense of. That sometimes >>>>>>>> means restating preconditions, sometimes pointing to boundary >>>>>>>> conditions, sometimes giving hints describing common causes of the >>>>>>>> exception - lots of different things that depend on the API, the >>>>>>>> activation context and the nature of the exception. The natural >>>>>>>> way >>>>>>>> to do this is to use natural language sentences. Please allow >>>>>>>> me to >>>>>>>> retain a straightforward way to construct these messages and to >>>>>>>> maintain the specificity and meaning of the messages. >>>>>>> IMHO, the level of details in the message is not needed: if the >>>>>>> exception >>>>>>> was thrown, the user should probably look at the documentation, >>>>>>> rather >>>>>>> than try another value at random; I'd say that it is harmful to >>>>>>> tempt the >>>>>>> users with something like "Pick another number". ;-) >>>>>>> >>>>>>> [Shouldn't we rather provide function where the rounding type is >>>>>>> an enum?] >>>>>>> >>>>>>> The main problem in those discussions is that you consider only >>>>>>> "toy" >>>>>>> situations, where the message generated by Commons Math should >>>>>>> make sense >>>>>>> wherever the exception is caught, and even if it is not caught. >>>>>> What you keep failing to acknowledge is that in many real world >>>>>> applications, reading exception stack traces and application logs >>>>>> that contain error messages is an important operational activity. >>>>>> Having clear error messages that make sense in the context of the >>>>>> stack trace or application activation context makes the job of those >>>>>> maintaining and debugging those applications easier. However hard >>>>>> we decide to make it, I will continue to provide these. >>>>> IMO, the real problem is old habits, period. Despite your repeating it >>>>> over and over, I never expressed anything in the sense of having less >>>>> information in the error messages. [I don't get what the stack >>>>> trace has >>>>> to do here. And I just gave you a real example where whatever details >>>>> CM tries to provide, it will _never_ be sufficient because it cannot >>>>> know why the call failed; I suggested that the _same_ amount of >>>>> (necessary but not sufficient) information could perhaps be provided >>>>> with "little block" patterns glued with "addMessage" (or an >>>>> improvement >>>>> thereof).] >>>>> Specific exceptions always provide more information than less specific >>>>> ones. Keeping low-level message (e.g. precondition failure) does not >>>>> preclude adding more specific messages when the context is known (that >>>>> happens in the code, and every little variant does not need to be >>>>> hard-coded in the currently overly long list of patterns). >>>>> My proposals were solely aimed at making the "preparation" of the >>>>> messages more efficient from a developer's perspective (e.g. no >>>>> scanning >>>>> of 300+ patterns). >>>>> Stalling the experiment in endless arguments makes it less and less >>>>> worth trying. >>>>> >>>>> All in all, the main argument seems to always be that if the user >>>>> cannot see the difference, it is not worth changing the design. >>>> Which is also a pragmatic and valid approach here imho. >>>> >>>> If there are no real user complaints about this topic (and I am not >>>> aware of any) and no other solution will greatly enhance the current >>>> state, it is really not worth doing it. >>>> >>>> Part of my day job is to debug very complex systems and the most >>>> important thing is that you get what you expect, i.e. according to the >>>> contract of a method, which btw also includes the method name. Detailed >>>> error messages are nice to have but not really required (as long as you >>>> understand the purpose of the code which any user/developer of CM >>>> should >>>> do). >>>> >>>> More meaningful error messages would make sense if our targeted >>>> audience >>>> are really end-users but I think this is a bit far-fetched. >>> >>> Not really. Does not have to be end users, just someone looking at >>> an application log that reproduces the messages or the stack traces >>> themselves. Sometimes operations / production support teams do not >>> have access or time to look at source code or javadoc. Informative >>> error messages that give more information about the failure can be >>> useful to these people. Sure, you can push all of that off to the >>> client app developers; but it can make *their* lives easier too to >>> get more information, especially information about parameter values, >>> which invariants were violated, etc. The simplest and easiest to >>> digest way to do that is to provide good error messages. >> >> If the contract is violated, then it is a bug and has to go to 3rd level >> support (aka developer) anyway and this you can see immediately if there >> is an IllegalArgumentException. >> >> For algorithm related problems, like MaxIterationExceededExceptions or >> similar ones can you really express why this happened? I think it is >> much more robust to take such exceptions into account in the first >> place, i.e. algorithms may not converge for certain inputs and a client >> app developer has to present a meaningful error (in the context of the >> application!) to a user or the log file. >> >> I even think that more detailed error messages give people the illusion >> that they can skip proper exception handling as CM already does it so >> well. >> >> Just an example: if you try to open a non-existent file with the Java >> API, do you get the error code of the respective system call on your >> operating system? No, you get a FileNotFoundException, but what do you >> do with it? Would you log the error message contained in the exception >> or a more specific one in the context of your application? >> >> Imho, the first option makes applications very hard to maintain. >> >> Now the Java API is quite easy to understand and a lot of people know it >> very well, but take the example further for any 3rd party library your >> application may be using. How is your operation engineer supposed to >> know all error states of all the used 3rd party libraries and put them >> in the right context? If he/she is lucky enough there is a an operations >> manual for their own application ... >> >> Interpreting and proper handling of 3rd party code is the job of the >> client app developer, and he/she has to do it right. If you may get an >> exception you have to take care about it, everything else will just >> create headaches. > > Very good account using the practical perspective of a multi-layered > application (I mean, where each layer is indeed developed by different > teams)! > [I had put forward this kind of arguments in my first raising of the > not-so-good feeling I had with the CM exception framework.] > > As a low-level library, the main focus must indeed to encapsulate error > conditions in the most flexible way for the layer next up (i.e. specific > exception classes) so that it can also act in a flexible way (catch, not > catch, catch and rethrow a context-specific exception). > > As I had said (too many times to be counted), this does not stand in > opposition with providing detailed error messages for the cases where > the intermediate layers do not care to catch the low level errors. > What top-level users can see from CM (through the stack trace) is the > best we can show (and that is quite fine by me, sorry to repeat myself > so often...). But my conviction is that we can do better internally (cf. > "small cleanup" of the error patterns list), and that we must do better > for the application or library developers who use CM as a component. > > Both these tasks should be thought about together; an improvement in > one area is likely to improve the other. [Again: I totally expect that > this will not change anything for a user who browses the stack trace > generated by a CM exception that was not caught.] > > So the real question was whether we are going to thwart any and all > attempts aimed at improvement on the basis of the single case of a > top-level user reading the low-level textual error messages.
If you have a good proposal to reduce the number of localized messages and thus make it easier to develop new code for CM I would be very much in favor of it. As Luc said, it could be quite hard to come up with patterns that really work in a multi-language context, but I did not try it myself or have seen proposals to overcome this complexity. I also did not follow so much the exception discussions as I am quite agnostic about it, but I wanted to point out that I consider good documentation and examples / user guide much more important and we should put our focus also on these issues (what I did try to do lately and am going to continue). Thomas --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org For additional commands, e-mail: dev-h...@commons.apache.org