1- using commonItems ;
1+ using commonItems ;
22using ImperatorToCK3 . Exceptions ;
33using log4net . Core ;
44using System ;
55using System . Globalization ;
66using System . Linq ;
7+ using System . Threading . Tasks ;
78
89namespace ImperatorToCK3 ;
910public static class Program {
1011 public static int Main ( string [ ] args ) {
12+ RegisterGlobalExceptionHandlers ( ) ;
13+
1114 try {
12- CultureInfo . CurrentCulture = CultureInfo . InvariantCulture ;
13- CultureInfo . CurrentUICulture = CultureInfo . InvariantCulture ;
14- CultureInfo . DefaultThreadCurrentCulture = CultureInfo . InvariantCulture ;
15- CultureInfo . DefaultThreadCurrentUICulture = CultureInfo . InvariantCulture ;
15+ SetInvariantCulture ( ) ;
1616
1717 var converterVersion = new ConverterVersion ( ) ;
1818 converterVersion . LoadVersion ( "configurables/version.txt" ) ;
@@ -28,7 +28,7 @@ public static int Main(string[] args) {
2828 if ( ex is AggregateException aggregateEx ) {
2929 ex = aggregateEx . Flatten ( ) . InnerExceptions . FirstOrDefault ( ) ?? ex ;
3030 }
31-
31+
3232 Logger . Log ( Level . Fatal , ex is UserErrorException ? ex . Message : $ "{ ex . GetType ( ) } : { ex . Message } ") ;
3333 if ( ex . StackTrace is not null ) {
3434 Logger . Debug ( ex . StackTrace ) ;
@@ -41,4 +41,44 @@ public static int Main(string[] args) {
4141 return - 1 ;
4242 }
4343 }
44+
45+ private static void RegisterGlobalExceptionHandlers ( ) {
46+ // Catch any unhandled exceptions from other threads.
47+ AppDomain . CurrentDomain . UnhandledException += ( sender , eventArgs ) => {
48+ if ( eventArgs . ExceptionObject is Exception ex ) {
49+ // If the exception is an AggregateException, we want the original inner exception's stack trace.
50+ if ( ex is AggregateException aggregateEx ) {
51+ ex = aggregateEx . Flatten ( ) . InnerExceptions . FirstOrDefault ( ) ?? ex ;
52+ }
53+
54+ Logger . Log ( Level . Fatal , ex is UserErrorException ? ex . Message : $ "{ ex . GetType ( ) } : { ex . Message } ") ;
55+ if ( ex . StackTrace is not null ) {
56+ Logger . Debug ( ex . StackTrace ) ;
57+ }
58+ } else {
59+ Logger . Log ( Level . Fatal , "An unhandled exception occurred, but it could not be identified." ) ;
60+ }
61+ Environment . Exit ( - 1 ) ; // Ensure the process exits with a non-zero code.
62+ } ;
63+ TaskScheduler . UnobservedTaskException += ( sender , eventArgs ) => {
64+ Exception ex = eventArgs . Exception ;
65+ // If the exception is an AggregateException, we want the original inner exception's stack trace.
66+ if ( ex is AggregateException aggregateEx ) {
67+ ex = aggregateEx . Flatten ( ) . InnerExceptions . FirstOrDefault ( ) ?? ex ;
68+ }
69+
70+ Logger . Log ( Level . Fatal , ex is UserErrorException ? ex . Message : $ "{ ex . GetType ( ) } : { ex . Message } ") ;
71+ if ( ex . StackTrace is not null ) {
72+ Logger . Debug ( ex . StackTrace ) ;
73+ }
74+ Environment . Exit ( - 1 ) ; // Ensure the process exits with a non-zero code.
75+ } ;
76+ }
77+
78+ private static void SetInvariantCulture ( ) {
79+ CultureInfo . CurrentCulture = CultureInfo . InvariantCulture ;
80+ CultureInfo . CurrentUICulture = CultureInfo . InvariantCulture ;
81+ CultureInfo . DefaultThreadCurrentCulture = CultureInfo . InvariantCulture ;
82+ CultureInfo . DefaultThreadCurrentUICulture = CultureInfo . InvariantCulture ;
83+ }
4484}
0 commit comments