Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exceptions not localizable #1024

Open
aphillips opened this issue Sep 20, 2021 · 14 comments
Open

Exceptions not localizable #1024

aphillips opened this issue Sep 20, 2021 · 14 comments
Labels
i18n-needs-resolution Issue the Internationalization Group has raised and looks for a response on.

Comments

@aphillips
Copy link

https://www.w3.org/TR/WebIDL/#dfn-DOMException

Exceptions have an error name, a DOMString, which is the type of error the exception represents, and a message, which is an optional, user agent-defined value that provides human readable details of the error.

The message attribute of DOMException does not provide a localization mechanism (a means of providing multiple language variations of the message or a means of negotiating the language). This has come up in a few recent spec reviews at W3C.

[I18N-ACTION-1051]

@domenic
Copy link
Member

domenic commented Sep 20, 2021

This is by design, to follow how JavaScript works. I think we would not change anything here without first getting changes in the JavaScript specification, and then we would just follow their lead.

@aphillips
Copy link
Author

@domenic I hear that ☹️. I will take it up with ECMA-402, et al.

As an alternative, do you think there's a way for us to provide optional elements here, for example via a localizable wrapper? Changing foundational elements is hard, since backwards compatibility with the installed base is rather important. But there is utility (that would be used by specs and applications) if we can provide it as an extension.

@domenic
Copy link
Member

domenic commented Sep 20, 2021

In my opinion no, although others may disagree. I think there are probably fundamental questions here about programming language design (e.g., are exception messages meant to be localizable at all; I haven't seen much work on that in other languages) which we should not preempt by going in a specific direction for the subset of web platform exceptions that use DOMException.

@bathos
Copy link
Contributor

bathos commented Sep 20, 2021

What would the basis of the language selection be? I hope it wouldn’t be system based given this isn’t user-facing text — the messages are used for debugging and the consumer of the messages is rarely the person driving the user agent.

The existing variation in these messages across agents is a source of pain (the more variation, the fewer searchable results available or useful information gets split across resources instead of unified).

@aphillips
Copy link
Author

@domenic Java has some (quite old and not-well-designed) support for localizable exceptions. I've done quite a lot with building localizable exception support in different frameworks in that language as a result.

A key factor in designs of this nature is what is called the "three locale problem": the data or resource being operated on is often in a language/has a locale. The service or system's operator has a preferred locale. And the client/caller has a locale. Each of these may need to resolve an exception to a human-readable string.

The argument against localizable exceptions is generally "it's for debugging only" (until it's the only value available for the user experience) or that maybe this was intentional in the language's design. I think it is okay to hardcode your log messages, but any message that can be seen by a user (!= developer) probably shouldn't be.

@bathos The best practice is (or rather, should be) locale-neutral errors with well-defined error values. This allows the consumer to localize the message and reduces the pain of trying to match up strings between systems/specifications. Data values can also be sent down the wire in a locale neutral fashion.

However, this doesn't work so well when specs design non-localizable/non-locale-neutral exceptions from the start. That is, this can never be localized:

return new FooException("Why can't we have nice things?");

@annevk
Copy link
Member

annevk commented Sep 21, 2021

FWIW, I consider us exposing error.message in userland to be a bit of a problem, especially with the value not being standardized. It allows for fingerprinting in certain cases (in particular when the values are not fixed strings) and it results in interoperability issues due to sites parsing the values in certain cases.

I think ideally we'd standardize upon the values, but that's quite a large effort. And leave localization to the developer console messages (which could be different and sometimes better, depending).

@aphillips which specifications define the error.message value? At least per current practice that seems wrong.

@bathos
Copy link
Contributor

bathos commented Sep 21, 2021

@annevk Web IDL refers to message values for both DOMException (and ES “NativeError” errors thrown from platform specs, too) as “user agent-defined” explicitly. (If this is what you meant — not 100% certain.)

@annevk
Copy link
Member

annevk commented Sep 21, 2021

Yeah, I would expect that currently all those values are implementation-defined, but I have a vague recollection of some specifications doing something different. And there's definitely a few places where web developers depend on the string value. (And as per my first paragraph above I would prefer defining the actual string everywhere to avoid fingerprinting and interoperability issues.)

@aphillips
Copy link
Author

DOMException has name, which behaves as a locale-neutral identifier (the fact that it's a string is fine--it just basically functions as an open-ended enum). I'm totally cool with name and think that specifications should define named exceptions. A named exception + data can be used to create localized messages on the client side with no fingerprinting and no need for language negotiation, etc. This is what I18N recommends to specifications. But...

But DOMException also has message which is "just a string" and is meant to be human-readable. I suppose localizing the message is a potential fingerprinting vector (to the degree that negotiating language/locale with anyone is a fingerprinting vector). Hardcoding all messages in English is not internationalized--I think our WG would prefer to provide for localization when it can be available?

IIRC, DOMException's ctor encourages the creation of message by not providing a name-only ctor.

@annevk
Copy link
Member

annevk commented Sep 22, 2021

What I'm saying on is that code depends on message in similar ways (though to a lesser extent) to name so localizing it isn't advisable. If we were to start over we should never have exposed message directly to websites, but here we are.

I suspect DOMException has message as the first argument to mimic JavaScript *Error constructors. I wouldn't really read anything into it.

@aphillips
Copy link
Author

Writing code that depends on a localizable value is a basic I18N anti-pattern. I don't disagree with you: some people's code probably does depend on the non-localization of some message values. But I'd like to encourage better architecture for the Web wherever possible.

It's always tricky to try to retrofit I18N best practices onto what is already a vast installed base. We are forced to live with compromises we wouldn't have made if given the opportunity earlier. In this case, DOMException is in a tight spot--it is foundational for many specifications, but it is tied to (and thus limited by) JavaScript.

If we can't fix DOMException directly, can we add guidance for specifications that extend it to write their own exceptions? Would that be an effective alternative?

(It's not that message is the first argument, it's that there is no new DOMException(name): you have to provide a message in order to provide a name)

@domenic
Copy link
Member

domenic commented Sep 22, 2021

I think we have a more fundamental question here, which I am encouraging you to take up with TC39: are JavaScript exception messages supposed to be localized? Are they supposed to be user-facing or developer-facing? My strong intuition is that they are developer-facing and not supposed to be localized, but instead the same across all locales to aid searchability etc.

@aphillips
Copy link
Author

Most developer's initial intuition is that Exceptions are "meant to be consumed by developers". In that case the localization of the message makes it an even greater pain in the ass to figure out what went wrong (and it's not helpful to localize).

The problem is that Exceptions, as used in distributed environments (such as the Web), often provide the only mechanism to convey information to the end user for certain kinds of user interaction failure. When that information is an opaque string, the recipient can have few alternatives than to display the message to the customer. This is especially true when the error conditions are implementation dependent and cannot be closely described/specified in advance and/or where the message is partially filled in with data values. It is important to remember that users of a system generally vastly outnumber developers.

So my plea in the previous comment would be to provide guidance to specification developers who are building exceptions (particularly those where the line is blurry as described above) on how to structure their exceptions to avoid problems (for both users and developers)--or to avoid using exceptions as a means of communicating these types of failure. Maybe that's a doc I18N should write that WebIDL can then footnote as appropriate.

@marcoscaceres
Copy link
Member

marcoscaceres commented Sep 23, 2021

@annevk wrote:

And leave localization to the developer console messages (which could be different and sometimes better, depending).

I think this gets to the core of the problem and perhaps we should move to standardize .message in future specs. At the same time, complementing this with console-only localization.

Imagine:

try {
   navigator.thingThatThrows();
} catch (err) {
   // Private message in my native language (UA-preference) that JS can't access
   // and only shows up in the browser console.
   console.localized(err);  
}

That would be very nice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
i18n-needs-resolution Issue the Internationalization Group has raised and looks for a response on.
Development

No branches or pull requests

6 participants