1- using System . Runtime . ExceptionServices ;
1+ using System . Linq . Expressions ;
2+ using System . Reflection ;
3+ using System . Runtime . ExceptionServices ;
24using System . Runtime . Serialization ;
35using dotnetCampus . Ipc . Exceptions ;
4- using dotnetCampus . Ipc . Utils ;
56
67#if UseNewtonsoftJson
78using Newtonsoft . Json ;
@@ -68,13 +69,13 @@ public void Throw()
6869 var exception = builder ( Message , ExtraInfo ) ;
6970 if ( StackTrace is { } stackTrace )
7071 {
71- var deserializedRemoteException = ExceptionHacker . ReplaceStackTrace ( exception , StackTrace ) ;
72- ExceptionDispatchInfo . Capture ( deserializedRemoteException ) . Throw ( ) ;
73- }
74- else
75- {
76- ExceptionDispatchInfo . Capture ( exception ) . Throw ( ) ;
72+ #if NET6_0_OR_GREATER
73+ exception = ExceptionDispatchInfo . SetRemoteStackTrace ( exception , stackTrace ) ;
74+ #else
75+ exception = ExceptionHacker . SetRemoteStackTrace ( exception , stackTrace ) ;
76+ #endif
7777 }
78+ ExceptionDispatchInfo . Capture ( exception ) . Throw ( ) ;
7879 }
7980 else
8081 {
@@ -89,13 +90,48 @@ public void Throw()
8990
9091 private static readonly Dictionary < string , Func < string ? , string ? , Exception > > ExceptionRebuilders = new ( StringComparer . Ordinal )
9192 {
92- { typeof ( ArgumentException ) . FullName ! , ( m , e ) => new ArgumentException ( m ) } ,
93+ { typeof ( ArgumentException ) . FullName ! , ( m , _ ) => new ArgumentException ( m ) } ,
9394 { typeof ( ArgumentNullException ) . FullName ! , ( m , e ) => new ArgumentNullException ( e , m ) } ,
94- { typeof ( BadImageFormatException ) . FullName ! , ( m , e ) => new BadImageFormatException ( m ) } ,
95- { typeof ( InvalidCastException ) . FullName ! , ( m , e ) => new InvalidCastException ( m ) } ,
96- { typeof ( InvalidOperationException ) . FullName ! , ( m , e ) => new InvalidOperationException ( m ) } ,
97- { typeof ( NotImplementedException ) . FullName ! , ( m , e ) => new NotImplementedException ( m ) } ,
98- { typeof ( NotSupportedException ) . FullName ! , ( m , e ) => new NotSupportedException ( m ) } ,
99- { typeof ( NullReferenceException ) . FullName ! , ( m , e ) => new NullReferenceException ( m ) } ,
95+ { typeof ( BadImageFormatException ) . FullName ! , ( m , _ ) => new BadImageFormatException ( m ) } ,
96+ { typeof ( InvalidCastException ) . FullName ! , ( m , _ ) => new InvalidCastException ( m ) } ,
97+ { typeof ( InvalidOperationException ) . FullName ! , ( m , _ ) => new InvalidOperationException ( m ) } ,
98+ { typeof ( NotImplementedException ) . FullName ! , ( m , _ ) => new NotImplementedException ( m ) } ,
99+ { typeof ( NotSupportedException ) . FullName ! , ( m , _ ) => new NotSupportedException ( m ) } ,
100+ { typeof ( NullReferenceException ) . FullName ! , ( m , _ ) => new NullReferenceException ( m ) } ,
100101 } ;
101102}
103+
104+ #if NET6_0_OR_GREATER
105+ #else
106+ file static class ExceptionHacker
107+ {
108+ static ExceptionHacker ( )
109+ {
110+ HackExceptionStackTraceLazy = new Lazy < Func < Exception , string , Exception > > ( ( ) => HackExceptionStackTrace , LazyThreadSafetyMode . None ) ;
111+ }
112+
113+ internal static Exception SetRemoteStackTrace ( Exception source , string stackTrace )
114+ {
115+ try
116+ {
117+ HackExceptionStackTraceLazy . Value ( source , stackTrace ) ;
118+ }
119+ catch
120+ {
121+ // 新框架已经处理了,不管旧框架的死活。
122+ }
123+ return source ;
124+ }
125+
126+ private static readonly Lazy < Func < Exception , string , Exception > > HackExceptionStackTraceLazy ;
127+
128+ private static readonly Func < Exception , string , Exception > HackExceptionStackTrace = new Func < Func < Exception , string , Exception > > ( ( ) =>
129+ {
130+ var source = Expression . Parameter ( typeof ( Exception ) ) ;
131+ var stackTrace = Expression . Parameter ( typeof ( string ) ) ;
132+ var remoteStackTraceStringField = typeof ( Exception ) . GetField ( "_remoteStackTraceString" , BindingFlags . NonPublic | BindingFlags . Instance ) ! ;
133+ var assign = Expression . Assign ( Expression . Field ( source , remoteStackTraceStringField ) , stackTrace ) ;
134+ return Expression . Lambda < Func < Exception , string , Exception > > ( Expression . Block ( assign , source ) , source , stackTrace ) . Compile ( ) ;
135+ } ) ( ) ;
136+ }
137+ #endif
0 commit comments