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.


Gilles


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org

Reply via email to