Hi Marcos,

Thanks for the comments. Replies below.

Norbert


On Aug 31, 2012, at 7:17 , Marcos Caceres wrote:

> Hi,
> I have a strong concern about the i18n API throwing an exception when an 
> unknown value is given as part of the option parameter for a constructor or 
> function.
> 
> For example, if I do:
> new v8Intl.DateTimeFormat(x, {year: "long"});
> 
> or:
> x.toLocaleTimeString("en", {year: "long"});
> 
> 
> I get in Chrome:
> "RangeError: Value long out of range for dateformat options property year".
> 
> Obviously, the above being that "year" cannot be "long".
> 
> Regardless, shouldn't bogus option values just be ignored for backwards 
> compat? Lets say a new type is added for any of the options supported by the 
> spec… then that new type will break backwards compat with old versions of the 
> API.

The way I understand it, backwards compatibility means that code that runs on 
an old version without exceptions continues to run on the new version with the 
same results. It does not mean that code that takes advantage of new 
capabilities in the new version will get the same results on the old version.

> Bogus hypothetical example - ES i18n.next introduces "formal", where the day 
> always has the first letter capitalised:
> 
> {day: "formal"}

Let's assume weekday - the day property currently has only "numeric" and 
"2-digit", therefore no letters.

> Because of this throw behaviour, the introduction of "formal" in a future 
> spec would potentially break all existing implementations today. If this 
> behaviour is left as is, (1) all calls to the i18n API will need to be 
> wrapped in try/catch (as a preemptive measure as the introductions of a new 
> option value would cause a throw). As a side effect, (2) users on old 
> browsers could be negatively impacted in the future without the knowledge of 
> the developer.

Applications only have to wrap their calls in try/catch if they use a new 
option value and want to run on old browsers that may not understand the new 
value. It's similar to how they have to check whether new API exists if they 
want to run on browsers that may not have that API yet.

Applications probably also would not have to wrap all calls - I think modern 
applications run a sequence of tests early on to detect which of the features 
they want to use are supported, and then adjust their behavior accordingly 
(polyfill, dumb down, ask the user to upgrade, ...).

In this specific case, checking whether "formal" is supported also lets 
applications decide what to do if "formal" is not supported. Most likely, it 
would choose "long" instead because it's closer to "formal" than "numeric", 
which would be the default used by the implementation.

> For the case of (1), developers may not even be aware that the API throws (or 
> has thrown) for a particular set of users using an outdated browser - I 
> personally found that it throws by accident. This would lead to (2), which 
> unfairly punishes users without the developer's knowledge - causing the 
> application to potentially stop working all together if the exception is not 
> caught.

Web developers generally need to be aware that there are different browser 
versions with different capabilities - that's not new. They decide whether IE 6 
is the baseline or IE 9, and then check for features that were introduced after 
the baseline version.

> IMHO, falling back to defaults, or by ignoring bogus values, would make the 
> API degrade gracefully without negatively impacting users (that is something 
> I really like about the API today - it does that if you feed it bogus 
> language tag or bogus option it does not understand). I think it should be 
> the same for option values.
> 

> I would also argue that having the above throw is inconsistent with the rest 
> of the API. The API already provides nice fallbacks to defaults in most 
> cases. For example, today (without i18n API support), calling any of the 
> to*LocaleString() simply "just works" - overcoming side-effect 2 above and 
> not punishing users with an exception. I think most developers would expect 
> that kind of fallback behaviour - you are guaranteed to get a 
> date/time/number that the user will understand (even if it's not as pretty as 
> a custom formatted one):
> 
> x.toLocaleTimeString("en", {foo: "bar"})
> //"12:00:00 AM"
> 
> x.toLocaleTimeString("klingon", {foo: "bar"})
> 
> //"12:00:00 AM"
> 
> …and so on… which is a great graceful fallback behaviour .

Yes and no. For structurally invalid language tags, it will throw. For 
structurally valid tags that it just doesn't recognize, it will use fallbacks. 
And there has been a lot of discussion about these fallbacks between some 
internationalizers who want a lot of flexibility to do what they think is best 
for the user, and TC 39 members who want behavior fully specified so that it's 
predictable and consistent across implementations.

> If the spec authors want to "warn" developers that they've used an 
> unsupported option value, maybe put into the spec to call "console.warn()" or 
> similar, if available. That allows developers to know they've used something 
> unsupported/unknown/or misspelled without punishing users - mobile safari and 
> Chrome do this already for meta-viewport values, so there is some helpful 
> precedence here. Yes, relying on "console.warn" is non standard, but this 
> could just be specified as non-normative text by just saying where 
> appropriate in the spec:
> 
> "Optionally, warn the developer that the option value is unsupported by, for 
> example, calling console.warn() or similar if available to the 
> implementation."
> 
> I think all modern browsers support the console object, and so does Node.js.

ECMAScript is used in more environments than just browsers and Node.js, and TC 
39 is generally staying away from making any specific requirements on the host 
environments. Clause 16 of the Language spec specifies precisely which errors 
must be reported when, but says nothing about how to report them.

> On the other hand, if the developer wants to check if what they inputed as 
> options is supported by the API, they can call .resolvedOptions() and 
> manually verify that all their options were understood by the browser. So:
> 
> var formatter = new v8Intl.DateTimeFormat(x, {day: "formal"}),
> options = formatter.resolvedOptions();
> 
> if(options.day !== "formal"){
> //no formal support, need to use something else
> options.day = "long";
> formatter = new v8Intl.DateTimeFormat(x, options),
> }
> … continue…

Actually, options.day !== "formal" does not mean that the implementation 
doesn't understand "formal" - it could also be that the requested locale 
happens not to have "formal" day names, while the implementations supports 
"formal" and other locales have such names.

> Note that there is precedence also in other APIs to not throw exceptions on 
> bogus options. For example, the Geolocation API does not throw in the 
> following cases and simply "just works" (tested in Chrome):
> 
> var l = function(e){console.log(e)};
> navigator.geolocation.getCurrentPosition(l, l, {maximumAge:"bananas"});
> navigator.geolocation.getCurrentPosition(l, l, {maximumAge:Node})
> navigator.geolocation.getCurrentPosition(l, l, {maximumAge:{}})

Is that good? Without looking at the WebIDL spec, what are the maximumAge 
values derived from "bananas", Node, or {}? Although, I'm afraid you can 
provide the same nonsense in some options of the Internationalization API...

> Kind regards,
> Marcos
> 
> --
> Marcos Caceres
> http://datadriven.com.au

_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to