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

Fix CultureNotFoundException when InvariantGlobalization is enabled #1213

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Humanizer/Configuration/Configurator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public static class Configurator
/// <summary>
/// A registry of formatters used to format strings based on the current locale
/// </summary>
public static LocaliserRegistry<IFormatter> Formatters { get; } = new FormatterRegistry();
public static LocaliserRegistry<IFormatter> Formatters { get; } = FormatterRegistry.CreateInstance();

/// <summary>
/// A registry of number to words converters used to localise ToWords and ToOrdinalWords methods
Expand Down
21 changes: 20 additions & 1 deletion src/Humanizer/Configuration/FormatterRegistry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,27 @@
{
class FormatterRegistry : LocaliserRegistry<IFormatter>
{
public FormatterRegistry() : base(new DefaultFormatter("en-US"))
public static FormatterRegistry CreateInstance()
{
try
{
return new FormatterRegistry(new DefaultFormatter("en-US"), false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This try-catch does not guarantee that exception is expected at exactly new DefaultFormatter("en-US") and in particular at _culture = new(localeCode) part. It can be thrown anywhere inside the FormatterRegistry constructor which creates many more cultures.

I think it need to be localized to something like this:

CultureInfo GetDefaultCulture() {
  try {
    return new CultureInfo("en-US");
  } catch (CultureNotFoundException) {
    return CultureInfo.InvariantCulture;
  }
}

And then check if default culture is invariant and if so then skip all other initializers.

}
catch (CultureNotFoundException)
{
// InvariantGlobalization is enabled, there is only one culture.
return new FormatterRegistry(new DefaultFormatter(CultureInfo.InvariantCulture), true);
}
}

private FormatterRegistry(IFormatter defaultFormatter, bool globalizationInvariant)
: base(defaultFormatter)
{
if (globalizationInvariant)
{
return;
}

Register("ar", new ArabicFormatter());
Register("de", new GermanFormatter());
Register("he", new HebrewFormatter());
Expand Down
4 changes: 4 additions & 0 deletions src/Humanizer/Localisation/Formatters/DefaultFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ public class DefaultFormatter : IFormatter
public DefaultFormatter(string localeCode) =>
_culture = new(localeCode);

/// <param name="culture">Culture to use.</param>
internal DefaultFormatter(CultureInfo culture) =>
_culture = culture;

public virtual string DateHumanize_Now() =>
GetResourceForDate(TimeUnit.Millisecond, Tense.Past, 0);

Expand Down