Assert your assumptions – .NET Core and subtle locale issues with WSL’s Ubuntu

I thought this was an interesting and subtle bug behavior that was not only hard to track down but hard to pin down. I wasn’t sure ‘whose fault it was.’

Here’s the story. Feel free to follow along and see what you get.

I was running on Ubuntu 18.04 under WSL.

I made a console app using .NET Core 3.0. You can install .NET Core here http://dot.net/get-core3

I did this:

dotnet new console
dotnet add package Humanizer –version 2.6.2

Then made Program.cs look like this. Humanizer is a great .NET Standard library that you’ll learn about and think “why didn’t .NET always have this!?”

using System;
using Humanizer;

namespace dotnetlocaletest
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(3501.ToWords());
}
}
}

You can see that I want the app to print out the number 3051 as words. Presumably in English, as that’s my primary language, but you’ll note I haven’t indicated that here. Let’s run it.

image

Note that app this works great and as expected in Windows.

scott@IRONHEART:~/dotnetlocaletest$ dotnet run
3501

Huh. It didn’t even try. That’s weird.

My Windows machine is en-us (English in the USA) but what’s my Ubuntu machine?

scott@IRONHEART:~/dotnetlocaletest$ locale
LANG=C.UTF-8
LANGUAGE=

Looks like it’s nothing. It’s “C.UTF-8” and it’s nothing. C in this context means the POSIX default locate. It’s the most basic. C.UTF-8 is definitely NOT the same as en_US.utf8. It’s a locate of sorts, but it’s not a place.

What if I tell .NET explicitly where I am?

static void Main(string[] args)
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo(“en-US”);
Console.WriteLine(3501.ToWords());
}

And running it.

scott@IRONHEART:~/dotnetlocaletest$ dotnet run
three thousand five hundred and one

OK, so things work well if the app declares “hey I’m en-US!” and Humanizer works well.

What’s wrong? Seems like Ubuntu’s “C.UTF-8” isn’t “invariant” enough to cause Humanizer to fall back to an English default?

Seems like other people have seen unusual or subtle issues with Ubuntu installs that are using C.UTF-8 versus a more specific locale like en-US.UTF8.

I could fix this in a few ways. I could set the locale specifically in Ubuntu:

locale-gen en_US.UTF-8
update-locale LANG=en_US.UTF-8

Fortunately Humanizer 2.7.2 and above has fixed this issue and falls back correctly. Whose “bug” was it? Tough one but in this case, Humanizer had some flawed fallback logic. I updated to 2.7.2 and now C.UTF-8 falls back to a neutral English.

That said, I think it could be argued that WSL/Canonical/Ubuntu should detected my local language and/or set locale to it on installation.

The lesson here is that your applications – especially ones that are expected to work in multiple locales in multiple languages – take “input” from a lot of different places. Phrased differently, not all input comes from the user.

System locale and language, time, timezone, dates, are all input as ambient context to your application. Make sure you assert your assumptions about what “default” is. In this case, my little app worked great on en-US but not on “C.UTF-8.” I was able to explore the behavior and learn that there was both a local workaround (I could detected and set a default locale if needed) and there was a library fix available as well.

Assert your assumptions!

Sponsor: Suffering from a lack of clarity around software bugs? Give your customers the experience they deserve and expect with error monitoring from Raygun.com. Installs in minutes, try it today!

© 2019 Scott Hanselman. All rights reserved.

     

Read more: feeds.hanselman.com

Leave a Reply

Your email address will not be published. Required fields are marked *

Skip to toolbar