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

Consider more forgiving DX #1735

Closed
2 tasks done
MichalBryxi opened this issue Nov 22, 2022 · 2 comments · Fixed by #1889
Closed
2 tasks done

Consider more forgiving DX #1735

MichalBryxi opened this issue Nov 22, 2022 · 2 comments · Fixed by #1889

Comments

@MichalBryxi
Copy link
Contributor

  • I am on the latest ember-intl version
  • I have searched the issues of this repo and believe that this is not a duplicate

Environment

  • Ember Version: ~4.8.0
  • Ember CLI Version: ~4.8.0
  • Ember Intl Version: ^5.7.2
  • Browser(s): Any :)
  • Node Version: v16.18.0

Steps to Reproduce

  1. As a developer I'm naturally having only limited resources / knowledge / foresight to what might happen. Especially when it comes to UI developers & APIs that might change / stop working without any warning and without prior testing.
  2. As a user I would rather have an app that works somehow rather than not at all. Having incorrectly displayed date, translation, etc. is not great, but it's way better than having an UI that does not work at all.

Because of the two points above I'd like to propose ember-intl not being overly aggressive on missing (undefined) values. Any code example below will blow up the entire application with the message attached:

## format-time
{{!-- Uncaught Error: <sandbox@helper:format-time::ember117> helper requires value attribute. --}}
{{!-- {{format-time this.nonexistent}} --}}

## format-number
{{!-- Uncaught Error: <sandbox@helper:format-number::ember117> helper requires value attribute. --}}
{{!-- {{format-number this.nonexistent}} --}}

## format-number(currency):
{{!-- Uncaught Error: <sandbox@helper:format-number::ember117> helper requires value attribute. --}}
{{!-- {{format-number this.nonexistent currency="USD" style="currency"}} --}}

format-time:
{{!-- Uncaught Error: <sandbox@helper:format-time::ember117> helper requires value attribute. --}}
{{!-- {{format-time this.nonexistent format="hhmmss"}} --}}

format-message:
{{!-- Uncaught Error: <sandbox@helper:format-message::ember117> helper requires value attribute. --}}
{{!-- {{format-message
  this.nonexistent
}} --}}

Since this.nonexistent is a variable that could come from many various sources (usually API) I as a developer have no control of it always being filled. Thus I will need to put if / else block around every single call of these helpers.

Now I'm not saying the developers should not do that to catch error states, but that's not how real world works and people will have code without those safeguards. And then a component that formats a date (or similar) just blows up entire application. And I think that should never happen.

Thoughts?

@sukima
Copy link

sukima commented Nov 22, 2022

In regards to ICU Message syntax what would you expect The number is: {nonexistent} to look like?

That said I did a little research and found that per the ECMAScript specs that the value is anything as it will be coerced to a number (defaulting with undefined).

I didn't look up the other formats. But it seems to me that it is safe to assume value is not a required parameter. It may be weird to have the format convert to NaN or something but I presume that is what is expected?

@sukima
Copy link

sukima commented Nov 22, 2022

I did a little more research:

Spec Expectation Interpretation
11.5.5 DateTime Format Functions If date is not provided or is undefined, then Let x be ! Call(%Date.now%, undefined). Else, Let x be ? ToNumber(date). Do not assert value
15.5.2 Number Format Functions If value is not provided, let value be undefined. Let x be ? ToNumeric(value). Do not assert value
13.5.3 FormatList list (which must be a List of String values) Must assert value

Since format-message uses the above internal implementations their expectations should be the same (i.e. do not assert). Also since lists are the only one I found that does need an assertion and that the ICU message syntax does not provide for lists it is reasonable that the format-message also should not assert values.

I am uncertain about the utility of allowing dynamic messages for format-message in app code instead perhaps using some alternative pattern that guarantees the existence of the value passed in (like hard coded strings or constants).

As for format-list the ICU guides recommend its use outside the message formatting:

Format the parameters separately (recommended)
You can format the parameter as you need before calling MessageFormat, and then passing the resulting string as a parameter to MessageFormat.
This offers maximum control, and is preferred to using custom format objects (see below).
~ https://unicode-org.github.io/icu/userguide/format_parse/messages/index#format-the-parameters-separately-recommended

Which I interpret that we should to the following with lists:

{{t "" items=(format-list items)}}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants