Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# - Getting Exception messages in English when the application is in another language?

I am trying to localize my program but I would like error messages that are sent to the developers to appear in English. I haven't been able to find a way to make this happen since it seems that if the UI culture is set to another language when an error is thrown, it is thrown in that language. Since I did not write this program myself, and it is quite large, I think it would be impractical to go create new try catch blocks to try and set the culture back to english whenever an error occurs or might possibly occur. Currently the CurrentCulture and DefaultThreadCurrentCulture are always set to be English throughout the entire application, while the CurrentUICulture is set to the end user's language.

As I workaround, I currently have a function that has been iterating through a list of errors (using System.Resources.ResourceSets (which I assume are Windows errors, but I also need a way to find the .NET errors so I can iterate through those). It string replaces matching errors in other languages and replaces them with their English equivalents to build a large message of errors to be sent to the developers whenever the application crashes. Really, I don't have much to translate as most of the message is a server stack trace and showing where the exception was thrown. The biggest problem is translating the Inner Exception message and sometimes the main exception message since sometimes the errors thrown don't appear in the ResourceSet and sometimes use formatting items like '{0}'.

Here is the code I have so far to translate the remaining errors. I'm still working on adding regex patterns to translate errors that use things like '{0}', so if anyone has suggestions for that or better ways to do this I'd appreciate suggestions.

    public static string TranslateExceptionMessageTest(string exmsg, Exception e, CultureInfo currentui)
    {
        CultureInfo test = Thread.CurrentThread.CurrentUICulture;
        string matchingstr = "";
        string newstr = exmsg;
        string resourcecollection = "";

        Assembly a = e.GetType().Assembly;
        ResourceManager rm = new ResourceManager(a.GetName().Name, a);
        ResourceSet rsOriginal = rm.GetResourceSet(currentui, true, true);
        ResourceSet rsTranslated = rm.GetResourceSet(new CultureInfo("en-US"), true, true);
        foreach (DictionaryEntry item in rsOriginal)
        {
            if (exmsg.Contains(item.Value.ToString()))
            {
                if (item.Key.ToString() == "Word_At") // sometimes with spanish errors this replaces words containing the letters 'en' with 'at'.
                {
                    string newat = "   " + item.Value.ToString() + " "; // this is the formatting the word 'at' appears with, in any culture I've tested.
                    matchingstr = "   " + rsTranslated.GetString(item.Key.ToString(), false) + " ";
                    newstr = newstr.Replace(newat, matchingstr);
                }
                else
                {
                    matchingstr = rsTranslated.GetString(item.Key.ToString(), false);
                    newstr = newstr.Replace(item.Value.ToString(), matchingstr);
                }
            }
            resourcecollection = resourcecollection + Environment.NewLine + "Key: " + item.Key.ToString() + Environment.NewLine + "Value: " + item.Value.ToString();
        }
        return newstr; // success
    }

I have also tried using the method posted here ( Exception messages in English? ) but without much luck. I still ended up with the same localized error messages. Here is the code where I know an error is being thrown but it doesn't seem like the catch block is doing anything to change the language. My ExceptionLogger class is set up the same way as in the Stackoverflow example with the addition of a line to write the error to a file. The error is being thrown at wcf.Client.Ping() (I don't care about the actual error. I'm using it to test).

 private void PreloadWcfDlls(object state)
 {
        if (Global.Inst.ServerMode == ApplicationServerMode.Unknown)
            return;

        try
        {
            using (var wcf = ClientGrabber.GetSchemaClient(Global.Inst.ServerMode))
            {
                wcf.Client.Ping();
            }
        }
        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();
        }
 }

If nothing else, is there a way I can get a list of all possible .NET Framework errors in English as well as in other languages? Is there a class I can access to get these from within my program or a list elsewhere? I've tried looking at sites like unlocalize.com and finderr.net but I really don't want to have to write something to crawl through all the pages to find every possible error.

Sorry if I'm completely missing something. I'm pretty new to C# and programming in general and this problem is driving me kind of crazy!

Edit: I forgot to add that I would prefer to avoid a solutions like these where you have to be constantly changing the CurrentUICulture:

Force exceptions language in English

Prevent exception messages from being translated into the user's language?

Or solutions where you delete language packs or something on the user's computer or just set the errors to be in English when debugging (these error logs will also be sent from an end users computer in the case that the application crashes and if they are using another language we need the errors logged in English).

Also, I know I could just google the error messages or use unlocalize.com or finderr.net to translate the messages but I think the other developers might kill me if they had to do that, hah. I guess if worse comes to worst I could query the unlocalize site? Seems like a real pain though.

like image 205
jalexis Avatar asked Jul 28 '15 15:07

jalexis


People also ask

What is C used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

Is it hard to learn C++?

Is C++ hard to learn? C++ is known to be one of the most difficult programming languages to learn over other popular languages like Python and Java. C++ is hard to learn because of its multi-paradigm nature and more advanced syntax.

What does %c mean in C?

%d is used to print decimal(integer) number ,while %c is used to print character . If you try to print a character with %d format the computer will print the ASCII code of the character.


1 Answers

Here you can find a solution for the problem. To make the long story short:

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
  }
}
like image 59
dmigo Avatar answered Sep 20 '22 07:09

dmigo