Humanizer
Humanizer copied to clipboard
ArgumentException with locale sk_SK when only Humanizr.Core is installed
Related to #647.
I'm hitting the issue on a Xamarin.iOS / Xamarin.Android app that only has the Humanizer.Core package installed. It is crashing for a user whose locale is sk_SK.
Exception: ArgumentException: The resource object with key 'DateHumanize_MultipleHoursAgo' was not found.
Stacktrace:
Humanizer.Localisation.Formatters.DefaultFormatter.Format(System.String resourceKey, System.Int32 number) in <3d8682191b624514bac93fecdf828edb#d241c975ca0c55d1909ef6d5e5b9b762>:0
Humanizer.Localisation.Formatters.DefaultFormatter.DateHumanize(Humanizer.Localisation.TimeUnit timeUnit, Humanizer.Localisation.Tense timeUnitTense, System.Int32 unit) in <3d8682191b624514bac93fecdf828edb#d241c975ca0c55d1909ef6d5e5b9b762>:0
Humanizer.DateTimeHumanizeStrategy.DateTimeHumanizeAlgorithms.DefaultHumanize(System.DateTime input, System.DateTime comparisonBase, System.Globalization.CultureInfo culture) in <3d8682191b624514bac93fecdf828edb#d241c975ca0c55d1909ef6d5e5b9b762>:0
Humanizer.DateTimeHumanizeStrategy.DefaultDateTimeHumanizeStrategy.Humanize(System.DateTime input, System.DateTime comparisonBase, System.Globalization.CultureInfo culture) in <3d8682191b624514bac93fecdf828edb#d241c975ca0c55d1909ef6d5e5b9b762>:0
Humanizer.DateHumanizeExtensions.Humanize(System.DateTime input, System.Boolean utcDate, System.Nullable`1[T] dateToCompareAgainst, System.Globalization.CultureInfo culture) in <3d8682191b624514bac93fecdf828edb#d241c975ca0c55d1909ef6d5e5b9b762>:0
I can also confirm adding the Humanizer package solves the issue.
If that's the case, then I'm guessing there's a Xamarin/Mono bug with resource fallbacks to the neutral (en-us) culture.
In general, I would always recommend using Humanizer directly since that contains all of the localizations.
Same issue here for Xamarin.Forms. Humanizer package is installed to .NET Standard and iOS/Android projects. But some users get the
ArgumentException: The resource object with key 'DateHumanize_MultipleHoursAgo' was not found.
I have one report from the field with this exception. I only have the Humanizer.Core including some other localized packages. Report happened from a phone configured for Polish which is not part of my included packages.
This is still broken. https://cdn.discordapp.com/attachments/704786002572738591/714542256429727854/Screenshot_20200525_231534.jpg https://github.com/rayshift/translatefgo/commit/f3613b3aa6d1a3231ff2c21a6b4e0a5827c79dd4#diff-b3c60ceedea4da7e766ceaa93d89c40dR290
I got same problem with .NET Core 3.1, reproducing easily enough with some DateTime values and Humanize(utcDate: false). Computer culture Russian and installed packages are: Humanizer.Core 2.8.26 and Humanizer.Core.ja 2.8.26 . As workaround i set app current culture to English (If it not Japanese).
I can concur. Have the same problem with Polish translation. Xamarin on Android.
Previously I did use Humanizer.Core 2.8.26 + Humanizer.Core.pl 2.8.26 There was an exception thrown. I've changed to Humanizer 2.8.26 - the problem still occurs.
I am using Xamarin Android (Andorid 9.0 (Api Level 28 - Pie)) with library as .NET Core 2.1
I am using .Humanize(utcDate: false);
Just had the same – or similar – error thrown in my ASP.NET Core application. What's weird, is that it was perfectly fine just a minute ago, but restarting the app caused the error to star occurring.
Edit: using .Humanize(culture: CultureInfo.InvariantCulture) fixed the issue.
System.ArgumentException: The resource object with key 'DateHumanize_MultipleHoursAgo' was not found (Parameter 'resourceKey')
at Humanizer.Localisation.Formatters.DefaultFormatter.Format(String resourceKey, Int32 number, Boolean toWords) in /_/src/Humanizer/Localisation/Formatters/DefaultFormatter.cs:line 121
at Humanizer.Localisation.Formatters.DefaultFormatter.GetResourceForDate(TimeUnit unit, Tense timeUnitTense, Int32 count) in /_/src/Humanizer/Localisation/Formatters/DefaultFormatter.cs:line 77
at Humanizer.Localisation.Formatters.DefaultFormatter.DateHumanize(TimeUnit timeUnit, Tense timeUnitTense, Int32 unit) in /_/src/Humanizer/Localisation/Formatters/DefaultFormatter.cs:line 49
at Humanizer.DateTimeHumanizeStrategy.DateTimeHumanizeAlgorithms.DefaultHumanize(DateTime input, DateTime comparisonBase, CultureInfo culture) in /_/src/Humanizer/DateTimeHumanizeStrategy/DateTimeHumanizeAlgorithms.cs:line 144
at Humanizer.DateTimeHumanizeStrategy.DefaultDateTimeHumanizeStrategy.Humanize(DateTime input, DateTime comparisonBase, CultureInfo culture) in /_/src/Humanizer/DateTimeHumanizeStrategy/DefaultDateTimeHumanizeStrategy.cs:line 16
at Humanizer.DateHumanizeExtensions.Humanize(DateTime input, Boolean utcDate, Nullable`1 dateToCompareAgainst, CultureInfo culture) in /_/src/Humanizer/DateHumanizeExtensions.cs:line 29
at Ogma3.Pages.Shared.Pages_Shared__ThreadCard.ExecuteAsync() in G:\VS Projects\Ogma3\Ogma3\Pages\Shared\_ThreadCard.cshtml:line 21
at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageCoreAsync(IRazorPage page, ViewContext context)
at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageAsync(IRazorPage page, ViewContext context, Boolean invokeViewStarts)
at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(ViewContext context)
at Microsoft.AspNetCore.Mvc.TagHelpers.PartialTagHelper.RenderPartialViewAsync(TextWriter writer, Object model, IView view)
at Microsoft.AspNetCore.Mvc.TagHelpers.PartialTagHelper.ProcessAsync(TagHelperContext context, TagHelperOutput output)
at Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner.<RunAsync>g__Awaited|0_0(Task task, TagHelperExecutionContext executionContext, Int32 i, Int32 count)
at Ogma3.Pages.Club.Pages_Club_Index.ExecuteAsync() in G:\VS Projects\Ogma3\Ogma3\Pages\Club\Index.cshtml:line 16
at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageCoreAsync(IRazorPage page, ViewContext context)
at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageAsync(IRazorPage page, ViewContext context, Boolean invokeViewStarts)
at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(ViewContext context)
at Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, String contentType, Nullable`1 statusCode)
at Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext, String contentType, Nullable`1 statusCode)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResultFilterAsync>g__Awaited|29_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.MigrationsEndPointMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
We are experiencing the same issue in xamarin forms for Polish language. Only Android - IOS works fine. Is there any possible way to fix this?
This issue is external as it has to do with resource localization/fallback. Please open an issue on https://github.com/dotnet/runtime (and feel free to link back to here/reference here).
so, @clairernovotny there is no way to fix it for Android?
My workaround is calling .Humanize(culture: CultureInfo.InvariantCulture) for the languages I did not include. I'm checking for those with CultureInfo.CurrentUICulture.TwoLetterISOLanguageName.
I have found out why that happens.
The error is sadly a bit misleading. Consider these code excerpts:
https://github.com/Humanizr/Humanizer/blob/606e958cb83afc9be5b36716ac40d4daa9fa73a7/src/Humanizer/Localisation/Formatters/DefaultFormatter.cs#L131-L138
https://github.com/Humanizr/Humanizer/blob/606e958cb83afc9be5b36716ac40d4daa9fa73a7/src/Humanizer/Localisation/Formatters/CzechSlovakPolishFormatter.cs#L5-L20
So, the actual missing resource keys are missing, they just show up invalid in the exception text. The missing ones are those with
_Paucalsuffix - there are no such resource keys.Generally, I'd say that it's a global issue. English (fallback) resources don't contain special, culture-specific-suffix additions. I have not come up with a good, quick fix for this. We'd probably need to somehow detect the fallback is used and retry with an unsuffixed resource key.
Originally posted by @amis92 in https://github.com/Humanizr/Humanizer/issues/776#issuecomment-1279525608