Exception Messages in English

Exception messages in English?

This issue can be partially worked around. The Framework exception code loads the error messages from its resources, based on the current thread locale. In the case of some exceptions, this happens at the time the Message property is accessed.

For those exceptions, you can obtain the full US English version of the message by briefly switching the thread locale to en-US while logging it (saving the original user locale beforehand and restoring it immediately afterwards).

Doing this on a separate thread is even better: this ensures there won't be any side effects. For example:

try
{
System.IO.StreamReader sr=new System.IO.StreamReader(@"c:\does-not-exist");
}
catch(Exception ex)
{
Console.WriteLine(ex.ToString()); //Will display localized message
ExceptionLogger el = new ExceptionLogger(ex);
System.Threading.Thread t = new System.Threading.Thread(el.DoLog);
t.CurrentUICulture = new System.Globalization.CultureInfo("en-US");
t.Start();
}

Where the ExceptionLogger class looks something like:

class ExceptionLogger
{
Exception _ex;

public ExceptionLogger(Exception ex)
{
_ex = ex;
}

public void DoLog()
{
Console.WriteLine(_ex.ToString()); //Will display en-US message
}
}

However, as Joe correctly points out in a comment on an earlier revision of this reply, some messages are already (partially) loaded from the language resources at the time the exception is thrown.

This applies to the 'parameter cannot be null' part of the message generated when an ArgumentNullException("foo") exception is thrown, for example. In those cases, the message will still appear (partially) localized, even when using the above code.

Other than by using impractical hacks, such as running all your non-UI code on a thread with en-US locale to begin with, there doesn't seem to be much you can do about that: the .NET Framework exception code has no facilities for overriding the error message locale.

How to handle translation of exception message?

Most exceptions are there for technical purposes, unless your operations and maintenance crew are also located in different countries, those exceptions should simply have messages in the language of the people who write and maintain the application.

The .NET framework contains localized exception messages. For me as a developer, that's very annoying, since the exception messages in my local language (Dutch) don't mean as much as the original English exception messages. However, it seems reasonable for Microsoft to localize those framework exception messages, since their target audience can be located anywhere.

Some types of exceptions however, are explicitly thrown to be displayed to the user. These are your ValidationException or BusinessLayerException. Their clear contract is to be displayed to the user. Of course you should localize those exception messages, but instead of translating them, it's often much better and easier to pull the exception message from a localized resource when throwing the exception:

throw new ValidationException(Resources.InvalidUserName);

Force exceptions language in English

Finally a "sharp" solution could be the following:

[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);

#if DEBUG
// Add this; Change the Locales(En-US): Done.
Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;
#endif

Application.Run(new Form1());
}

However I'd like a solution without modifications in the project code.

From MSDN:

The CurrentUICulture property will be
set implicitly if an application does
specify a CurrentUICulture. If
CurrentUICulture is not set explicitly
in an application's code, it is set by
the GetUserDefaultUILanguage function
on Windows 2000 and Windows XP
Multilingual User Interface (MUI)
products where the end user can set
the default language. If the user's UI
language is not set, it will be set by
the system-installed language, which
is the language of the operating
system's resources.

If an application is Web-based, the
CurrentUICulture can be set explicitly
in application code to the user's
browser accept language.

Visual Studio returns Dutch exceptions instead of English

Maybe try this out:
https://ifyoudo.net/post/2019/09/07/how-to-uninstall-a-net-language-pack-for-good

  1. Press Windows key + R
  2. Type: LPKSETUP
  3. Hit Enter
  4. Click Uninstall display languages
  5. Choose the language then click Next

why exception.message is not in english

The message in the exception is created when it's first thrown and that will be in whatever culture the code is compiled under. You cannot change this.

As this is WebClient the only solution is to make sure you have the English language version of .NET installed.

How to completely avoid localized .NET exception messages

Remove any .NET language packs. According to this ("The .NET Framework 4.5 Language Pack contains translated error messages and other UI text for languages other than English. If you don't install a language pack, this text is displayed in English"), it should be enough.

Configure NLog to write exception messages in English

I found a solution with some help. See github.com/NLog/NLog/issues/172 thanks to Julian

It is possible to write a custom WrapperLayoutRenderer that switches the culture before the exception is logged.

namespace NLog.LayoutRenderers.Wrappers
{
[LayoutRenderer("InvariantCulture")]
[ThreadAgnostic]
public sealed class InvariantCultureLayoutRendererWrapper : WrapperLayoutRendererBase
{
protected override string Transform(string text)
{
return text;
}

protected override string RenderInner(LogEventInfo logEvent)
{
var currentCulture = Thread.CurrentThread.CurrentUICulture;
try
{
Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture;
return base.RenderInner(logEvent);
}
finally
{
Thread.CurrentThread.CurrentUICulture = currentCulture;
}
}
}
}

It must be registered before any logger is created

ConfigurationItemFactory.Default.LayoutRenderers.RegisterDefinition("InvariantCulture", typeof(InvariantCultureLayoutRendererWrapper));

And can be used like that in the config

layout="${longdate}|${level:uppercase=true}|${logger}|${message}|${InvariantCulture:${exception:format=tostring}}"


Related Topics



Leave a reply



Submit