Skip to content

Commit 9d98df9

Browse files
committed
新框架不再使用反射替换异常的堆栈
1 parent f22294f commit 9d98df9

File tree

2 files changed

+51
-39
lines changed

2 files changed

+51
-39
lines changed

src/dotnetCampus.Ipc/CompilerServices/GeneratedProxies/Models/GeneratedProxyExceptionModel.cs

Lines changed: 51 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
using System.Runtime.ExceptionServices;
1+
using System.Linq.Expressions;
2+
using System.Reflection;
3+
using System.Runtime.ExceptionServices;
24
using System.Runtime.Serialization;
35
using dotnetCampus.Ipc.Exceptions;
4-
using dotnetCampus.Ipc.Utils;
56

67
#if UseNewtonsoftJson
78
using 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

src/dotnetCampus.Ipc/Utils/ExceptionHacker.cs

Lines changed: 0 additions & 24 deletions
This file was deleted.

0 commit comments

Comments
 (0)