commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ole Ersoy <ole.er...@gmail.com>
Subject Re: [math] UnexpectedNegativeIntegerException
Date Thu, 06 Sep 2012 16:08:09 GMT
I really like where the below discussion is going.  Just wanted to provide another code example
of some of the ideas I was toying with.  It might be too cumbersome, but I figured I'd throw
it out there.

The PoissonDistribution throws a NotStrictlyPositiveException.  I imagine several other classes
throw this as well, and it seems like it could be challenging to figure out the exact context
of where the exception was thrown without manually reading the stack trace or doing a lot
of vodoo.  The end goal of this would be to show to the user / operation manager the "paramterizedMessage"
contained in the InternalNotStrictlyPositiveException below...

So I was thinking what if it did something like this:

         if (p <= 0) {
             throw new InternalNotStrictlyPositiveException(p);
         }

Where the exception is internal to the PoissionDistribution and looks like this:

     public class InternalNotStrictlyPositiveException extends NotStrictlyPositiveException
     {
     	public static final String parameterizedMessage =
     		"The mean provided to the PoissonDistribution must be strictly positive.  It is {0,
number, #.##}";

		public InternalNotStrictlyPositiveException(
				Number value) {
			
     		super(MessageFormat.
     				format(
     						parameterizedMessage,
     						value), value);			
		}
     }

Now it can be caught like this:

try
{
//Code that can throw instances of not strictly positive exception from many different classes
}
catch(PoissonDistribution.InternalNotStrictlyPositiveException e)
{
//Now I know exactly where the problem is.  If I want to localize the message
//I could do something like:
String localizedPattern = LocalizedMessagePatternLookup(locale, e);
String localizedMessage = MessageFormat(localizedPattern, e.getValue);
}

The exception is used as the key, because it's unique to the "Solution".

Cheers,
- Ole




On 09/06/2012 07:02 AM, luc wrote:
> Le 2012-09-06 00:38, Gilles Sadowski a écrit :
>> On Wed, Sep 05, 2012 at 08:16:34PM +0200, Luc Maisonobe wrote:
>>> Le 05/09/2012 19:09, Ole Ersoy a écrit :
>>> > Hi Gilles,
>>> >
>>> > On 09/04/2012 06:48 PM, Gilles Sadowski wrote:
>>> >> Hello.
>>> >>
>>> >> There are ideas that sound good we experiment with them within a limited
>>> >> framework (like a course on programming, for example); and then become
a
>>> >> nightmare when you find yourself constantly trying to get around them.
>>> >> I mean that a design idea might look nice, and only when you are long
way
>>> >> into implementing the consequences of that idea, you discover that it
was
>>> >> not such a good one after all.
>>> >
>>> > Been there :)
>>> >
>>> >>> As a user of commons math I think it would be great if a each exception
>>> >>> mapped to a "One of a kind problem". So instead of having a
>>> >>> NegativeIntegerException, which is generic and could be used in
a lot
>>> >>> of places, have SuperDuperOptimizerNegativeIntegerException, which
is
>>> >>> only thrown in one place.
>>> >>>
>>> >>> Is this possible?
>>> >>
>>> >> Possible, it is. But have you imagined how many different exceptions
that
>>> >> would entail?
>>> >
>>> > I really did and thought maybe this is just crazy.
>>> >
>>> >> Currently, there are more than 1000 "throw" statements in CM.
>>> >>
>>> >> My position is to have a mapping between "exception type" and "problem
>>> >> kind"; your suggestion looks like a mapping between "exception type"
and
>>> >> "problem location".
>>> >
>>> > I would rephrase my suggestion as a mapping between "exception type" and
>>> > "solution". So if you know the exception type, you immediately know how
>>> > to provide options to the person responsible for the operation.
>>> >
>>> >> Besides the drawback of an enormous increase of the number of classes,
>>> >> tying
>>> >> the exception to its place of use is redundant with the information
>>> >> already
>>> >> provided in the stack trace.
>>> >
>>> > I agree. I really meant "Solution". It seems that we are already at
>>> > the point where exceptions should provide parameters from the instance
>>> > that threw the exception for the purpose of UI display, logging, etc.,
>>> > so if it's going to be that specific, then why not make it so specific
>>> > that it can only have one possible message and one set of solutions
>>> > specific to the context.
>>> >
>>> >>
>>> >> [One of the most useful rules in programming is code reuse; it would
be a
>>> >> waste of a programmer's time to create a new exception class just because
>>> >> it is intended to be thrown from a different place.]
>>> >
>>> > I agree.
>>> >
>>> > The main reason I threw my 2 cents in is because it seem like the design
>>> > of the exceptions was getting very complicated with the inclusion of
>>> > localization, unrolling of diagnostic contexts (Not sure if I said that
>>> > right...), etc. and there has to be a simpler way.
>>> >
>>> > For example it seems like localization should be worried about after you
>>> > catch the exception and you know what to do with it. I like that
>>> > localization is part of commons math, but to me it seems that it should
>>> > be a utility that can be used for message display once an action has
>>> > been decided upon post catching the exception. Right now it seems that
>>> > localization has become a constraint on exception design.
>>>
>>> Looking at localization after the exception has been caught is possible
>>> only once you are sure all exceptions are unique (which is the core of
>>> your proposal). As our use and reuse exceptions everywhere, this is
>>> simply not possible.
>>>
>>
>> I'm not so sure that every exception must have a single use. In fact, it
>> may be a quite appropriate usage of your request: Assuming that the
>> "getPatterns" and "getArguments" methods are available, what we do now
>> (formatting of the exception message) inside the "getMessage" of
>> "ExceptionContext" can be done after catching the exception:
>>
>> try {
>> // Computations that can throw CM exceptions.
>> } catch (MathRuntimeException e) {
>> if (allIsLost) {
>> // Build a localized message.
>> final List<LocalizedFormats> patterns = e.getContext().getPatterns();
>> final List<Object[]> args = e.getContext().getArguments;
>> final String msg = TranslatorService.buildMessage(patterns,
>> args);
>>
>> // Rethrow.
>> throw new UserException(msg);
>> }
>>
>> // Handle the exception at this level.
>> }
>>
>> [The "TranslatorService" would not be part of CM, but a side project
>> only depending on a "MessagePattern" enum provided by CM.]
>
> This would be fine to me as long as without the service we could still have humanly readable
> messages in (Apache) English.
> We could even revive an old Commons project for that (i18n in the sandbox, and it could
even
> depend on cal10n you proposed years ago).
>
>>
>> Did I overlook something obvious (e.g. a "nice idea that is not so"...)?
>
> getLocalizedMessage is not a [math] specific thing, it belongs to the regular Java API.
It
> is used by debuggers in integrated development environments.
>
> So your exemple above should probably be rewritten to provide both the raw and the localized
> message. Simply building UserException with a translated fixed String is not enough.
But moving
> all the framework we have set up (and which does support this feature) in a side project
so
> users can build their exceptions from that would be fine.
>
>>
>> What I find nice (caveat notwithstanding) is that it would take the load of
>> localization off CM. ["LocalizedFormats" just needs to be a "MessagePattern"
>> without being "Localizable"]. We'd just keep the formatting of the default
>> (English) message.
>
> Yes.
>
> best regards,
> Luc
>
>>
>>
>> Regards,
>> Gilles
>>
>> P.S. This is _not_ a proposal. ;-)
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>> For additional commands, e-mail: dev-help@commons.apache.org
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org
>
>

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


Mime
View raw message