Le 02/09/2012 14:00, Gilles Sadowski a écrit :
> Hi again.
> 
>>>
>>>>
>>>>>>
>>>>>>>>> [...]
>>>>>>>>> I encountered this need in two different cases. The first one was to
>>>>>>>>> identify very precisely an error type, even with finer granularity 
>>>>>>>>> than
>>>>>>>>> exception type. Parsing the error message to recognize the exception 
>>>>>>>>> is
>>>>>>>>> evil, checking the enumerate used in the pattern is less evil. The
>>>>>>>>> second case was when I needed to create a more elaborate message by
>>>>>>>>> combining some information provided by the caller, and some 
>>>>>>>>> information
>>>>>>>>> extracted from the exception. Here again, parsing is evil but getting
>>>>>>>>> the parameters is fine.
>>>>>>>>
>>>>>>>> Maybe you missed my point (same as above), as it applies here too: You 
>>>>>>>> can
>>>>>>>> get the parameters through the accessors (of the specific exception 
>>>>>>>> types).
>>>>>>>> We created the "context" so that additional parameters can be set and
>>>>>>>> retrieved ("key/value" pairs). I still do not understand why one should
>>>>>>>> resort to extract something from the pattern.
>>>>>>>> [The pattern is unfortunately "public" whereas it should be an
>>>>>>>> "implementation detail".]
>>>>>>>
>>>>>>> I don't "extract" something from the pattern, I just check if it is a
>>>>>>> known and expected enumerate I want to handle specifically or something
>>>>>>> else.
>>>>>>
>>>>>> Maybe I should see the actual code before we go on discussing this. Of
>>>>>> course you are free to do whatever the API of CM lets you do. I just have
>>>>>> the feeling that I would do it otherwise... :-}
>>>>>
>>>>> Here is an example I encountered two minutes ago, while working on
>>>>> adding the exception throws statements in the ode package.
>>>>>
>>>>> The computeParameterJacobian may throw a MathIllegalArgumentException
>>>>> (in the current subversion repository, I have seen it throws an
>>>>> IllegalArgumentException, which is wrong). In the following piece of
>>>>> code, I need to check the exception I get is really a
>>>>> LocalizedFormats.UNKNOWN_PARAMETER or something else:
>>>>>
>>>>>
>>>>>   delayedExcpetion = null;
>>>>>   for (ParameterJacobianProvider provider: jacobianProviders) {
>>>>>
>>>>>     try {
>>>>>
>>>>>       provider.computeParameterJacobian(...);
>>>>>       return;
>>>>>
>>>>>     } catch (MathIllegalArgumentException miae) {
>>>>>       List<Localizable> patterns = miae.getContext().getPatterns();
>>>>>       if (patterns.contains(LocalizedFormats.UNKNOWN_PARAMETER)) {
>>>>>         // temporarily ignore, until we have checked all providers
>>>>>         delayedException = miae;
>>>>>       } else {
>>>>>         // this is another problem, report it
>>>>>         throw miae;
>>>>>       }
>>>>>     }
>>>>>
>>>>>   }
>>>>>
>>>>>   if (delayedException != null) {
>>>>>     // none of the providers did handle the parameters
>>>>>     throw miae;
>>>>>   }
> 
> I'd like to stress that using exceptions for control flow is, by default, an
> anti-pattern.  It should pose question about how to improve CM so that you
> don't have to fall back on this kind of construct...

Please don't focus only on this example but look at the rest of the
arguments. Retrieving the building blocks from one exception to build
something else meaningful to the user application is *not* control flow.

> 
> IIUC the above code, the problem that might occur is not a complex
> computation that fails, but a "wrong" usage (from the viewpoint of the
> called code) due to a missing parameter. Wouldn't it be possible to have a
> checking method in "ParameterJacobianProvider" such as
> 
>   public boolean isValidParameter(String ... paramNames) {
>     // return "true" if all passed parameters are known,
>     // false otherwise.
>   }
> 
> and "somehow" make the check in order to avoid making a call that will fail?

You don't understand. You focus on *one* example, with *one* exception
and don't look at it as one case of a more general problem. I
unfortunately cannot provide an example for every hundred of patterns we
have in the enumerate and wait for you to answer with one specific
precondition checker for each one. Also bear in mind that it is not
always possible to know beforehand some call will lead to an error.
Preconditions are not a solution to everything and errors don't mean
user did a "wrong" use or sent "illegal" parameters. There are many
cases when you cannot know something will fail and you have to first try
it, then get an exception, attempt to identify it and finally do what is
possible at your level. But for this, you need some valuable information
that is already carried by the exception, but currently hidden and with
no accessor.

What I ask for (read make a request as a user) is for two getters for
parameters that already exist. I need these pieces of data and I don't
want you to judge why I need them. Without these getters, I would be
forced to do even uglier hacks like parsing the message or using
reflection to get the fields.

best regards,
Luc

> 
> 
> Best regards,
> Gilles
> 
>> [...]
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
> For additional commands, e-mail: dev-h...@commons.apache.org
> 
> 


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

Reply via email to