Skip to content

Improve handling of unsupported locales #900

Open
@chadpav

Description

Is your feature request related to a problem? Please describe.
After localizing an app with Date and Number formatters I unexpectedly found that my app was throwing exceptions for a small % of devices that use oddball locales. For example, I have a handful of users with their devices set to la-US which is Latin in the US.

On app start, I'm using the findSystemLocale method from intl_standalone.dart and storing the system locale. I first discovered that this method has to be called or the package won't know the users locale.

// Initialize the intl package so that it has the correct locale
  final systemLocale = await findSystemLocale();
  await initializeDateFormatting(systemLocale);
  logger.debug('Found system locale and initialized date formatting: $systemLocale');

Then, I discovered that the format methods from the package will throw ArgumentExceptions if a locale is not supported... even though the locale came from the findSystemLocale() method.

Ex: this will throw if you set your device to la-US:

extension currencyFormatted on double {
  /// $1,000.00 (en_US)
  String toCurrencyFormat(String localeIdentifier) {
    return NumberFormat.simpleCurrency(locale:localeIdentifier).format(this);
  }
}

I ended up writing helper methods that use a method I found while reading the INTL package source code:

String getExceptionSafeNumberFormatLocale(String localeIdentifier) {
  return NumberFormat.localeExists(localeIdentifier) ? localeIdentifier : 'en_US';
}

String getExceptionSafeDateFormatLocale(String localeIdentifier) {
  return DateFormat.localeExists(localeIdentifier) ? localeIdentifier : 'en_US';
}

Then I always use that helper when formatting:

extension currencyFormatted on double {
  /// $1,000.00 (en_US)
  String toCurrencyFormat(String localeIdentifier) {
    return NumberFormat.simpleCurrency(locale: getExceptionSafeNumberFormatLocale(localeIdentifier)).format(this);
  }
}

While I have a solution it seems like a lot of knowledge is required to avoid app crashing bugs. I haven't deployed this code yet so I might learn something else.

Also, there are multiple examples of people hitting this issue and reporting bugs. A good solution might avoid all of these:
#818
#752
#745
#406
... lots more.

Describe the solution you'd like
I have ideas but you guys probably know best. I'm providing feedback. Ideally, as a consumer of this package I would want to fall into a pit of success.

  1. At the package level you could provide a way to set a fallback locale. Then if findSystemLocal() returns something the package doesn't support, all format methods would have a fallback to use instead.
  2. Clearly document known ArgumentExceptions everywhere. I don't remember where I saw it but it wasn't obvious and didn't help all of us from shipping app crashing bugs first.
  3. Document helper method that can be used to check if a locale exists or not. I found this in the source code and used it for my work around.
NumberFormat.localeExists(localeIdentifier) 
DateFormat.localeExists(localeIdentifier) 
  1. If the list of supported locales is determined at the package level then provide a helper at that level so I don't have to check NumberFormat and DateFormat separately. Maybe next to the findSystemLocale() method in the intl_standalone.dart file?
  2. Would it make sense to always attempt to fallback to the country code? If I pass in la-US and that isn't supported, could you just format the Date or Number using the US region? That's generally what I would want anyway.

Describe alternatives you've considered
I documented what I did in my code here:
#818 (comment)

Additional context
Add any other context or screenshots about the feature request here.

Metadata

Assignees

No one assigned

    Labels

    type-enhancementA request for a change that isn't a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions