1

Currentlly I'm using this approach to convert an exception to an exception that will translate the original exception message to English language:

C#:

[DebuggerStepThrough()]
[Extension()]
public Exception ToEnglish<T>(T ex) where T : Exception
{

    CultureInfo oldCI = Thread.CurrentThread.CurrentUICulture;
    Exception exEng = default(Exception);

    Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-US");

    // Instance Exception one time to retrieve an English message.
    exEng = (Exception)Activator.CreateInstance(ex.GetType);

    // Instance Exception a second time to pass additional parameters to its constructor.
    exEng = (Exception)Activator.CreateInstance(ex.GetType, new object[] {
        exEng.Message,
        ex
    });

    Thread.CurrentThread.CurrentUICulture = oldCI;

    return exEng;

}

//=======================================================
//Service provided by Telerik (www.telerik.com)
//Conversion powered by NRefactory.
//=======================================================

Vb.Net:

<DebuggerStepThrough>
<Extension>
Public Function ToEnglish(Of T As Exception)(ByVal ex As T) As Exception

    Dim oldCI As CultureInfo = Thread.CurrentThread.CurrentUICulture
    Dim exEng As Exception

    Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-US")

    ' Instance Exception one time to retrieve an English message.
    exEng = DirectCast(Activator.CreateInstance(ex.[GetType]), Exception)

    ' Instance Exception a second time to pass additional parameters to its constructor.
    exEng = DirectCast(Activator.CreateInstance(ex.[GetType], New Object() {exEng.Message, ex}), Exception)

    Thread.CurrentThread.CurrentUICulture = oldCI

    Return exEng

End Function

( I'm aware that some exception messages are only partially defined in English )

However, I'm not totally satisfied with the results, because firstlly I'm not returning the same runtime type, and secondlly the stack-trace of the resulting exception is empty so I need to to preserve the info of the original exception in the InnerException property of the resulting exception.

Then, I would like to improve the function to meet there requeriments:

    1. Return an Exception of the same Type that passed to the type-parameter (eg. FileNotFoundException).
    1. In the resulting exception, re-create/preserve the stack-trace (and TargetSite property), in English language.

I'm not really sure if point number 2 could be accomplished because possible stack limitations?, anyways I'm asking to know, how I could do both things?.

ElektroStudios
  • 19,105
  • 33
  • 200
  • 417
  • To return the actual exception type, have your method return `T` (and change all casts accordingly). As for (un)localizing exception messages, is that worth the trouble? The localized messages I've seen so far were fairly easy to look up/translate with Google. – Pieter Witvoet Nov 21 '15 at 15:41
  • Thanks for comment... I know that the function should return T (that's why I'm asking for achieve...), but is not simple as changing the return type and the castings, the reflection logic should be adapted to instance the proper type of exception with its proper number of arguments, lets say for example an `InvalidEnumArgumentException` which has 4 overloads. There is where Im lost of ideas. – ElektroStudios Nov 21 '15 at 15:49
  • 2
    I see what you mean... What you can try is to use parameterless constructors whenever possible. If the exception type doesn't have such a constructor, you could pick the c'tor with the least amount of parameters, passing in dummy values (null, 0, etc.). Then copy the content of all fields (including non-public and private base type fields). Of course, that'll probably overwrite some localized values, which is what you want to prevent... I'd probably start looking for alternative solutions to your actual problem before continuing down this path. – Pieter Witvoet Nov 21 '15 at 16:38
  • 1
    Looks like at least `Exception` itself doesn't store any localized text in its fields - localization appears to happen in the various property getters. Still, there's no guarantees that all exception types will behave the same, or that they will continue to do so across different versions of the libraries they're part of. What's the actual use-case for (un)localizing those messages and stacktraces? – Pieter Witvoet Nov 21 '15 at 16:57
  • Wouldn't setting `UICulture` to *"en-US"* and `Culture` to lets say *"es-ES"* be sufficient? – Bjørn-Roger Kringsjå Nov 21 '15 at 17:11
  • @Pieter Witvoet `What's the actual use-case for (un)localizing those messages and stacktraces?` I'm writting a general purpose API then I started writting the method above considering that would be great to have an easy-of-use helper method that could "transform" any kind of exception (message and stack-trace) to English for logging/reporting purposes for example to send the details via email to the author of the app that caused the exception, preserving the localized language of the UI of the app, 'cause a stacktrace in a unknown language could be very bad to understand. – ElektroStudios Nov 21 '15 at 17:19
  • I haven't been able to test this, but for exceptions that fetch localized text in their property getters, setting the current thread's `CurrentCulture` before logging them *should* be sufficient - no copy required. Either way, if this is important for your service then you should probably take some time to inspect the source code of at least the most common exception types to see which ones need special treatment and which ones don't. – Pieter Witvoet Nov 21 '15 at 18:10
  • I don't understand this question. Why do you want to use `T` as the new exception type instead of the actual run-time type of the exception? And if you want the run-time type of the new exception to be `T`, why don't you just use `typeof(T)` instead of `ex.GetType()` when creating the new exception? As far as the stack trace goes, if you are using `ex` as the inner exception of the new exception, that will of course include the original stack trace. Given that a stack trace is just symbols (and occasionally a tiny bit of boilerplate), what would it mean to _translate to English_ a stack trace? – Peter Duniho Nov 22 '15 at 00:30

0 Answers0