Skip to content

Commit d667998

Browse files
committed
capture exception on Exceptions.SetError, restore in ThrowLastAsClrException
1 parent 3d95e60 commit d667998

File tree

2 files changed

+27
-9
lines changed

2 files changed

+27
-9
lines changed

src/runtime/exceptions.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Reflection;
3+
using System.Runtime.ExceptionServices;
34
using System.Runtime.InteropServices;
45

56
namespace Python.Runtime
@@ -285,6 +286,12 @@ public static void SetError(Exception e)
285286

286287
IntPtr op = Converter.ToPython(e);
287288
IntPtr etype = Runtime.PyObject_GetAttrString(op, "__class__");
289+
#if NETSTANDARD
290+
var exceptionInfo = ExceptionDispatchInfo.Capture(e);
291+
Runtime.XDecref(op);
292+
op = Converter.ToPython(exceptionInfo);
293+
#endif
294+
288295
Runtime.PyErr_SetObject(etype, op);
289296
Runtime.XDecref(etype);
290297
Runtime.XDecref(op);

src/runtime/pythonexception.cs

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,26 +66,30 @@ internal static Exception ThrowLastAsClrException()
6666
IntPtr gs = PythonEngine.AcquireLock();
6767
try
6868
{
69-
Runtime.PyErr_Fetch(out var pyTypeHandle, out var pyValueHandle, out var pyTracebackHandle);
69+
Runtime.PyErr_Fetch(out var type, out var value, out var traceback);
7070
try
7171
{
72-
var clrObject = ManagedType.GetManagedObject(pyValueHandle) as CLRObject;
73-
if (clrObject?.inst is Exception e)
74-
{
72+
var clrObject = ManagedType.GetManagedObject(value) as CLRObject;
7573
#if NETSTANDARD
76-
ExceptionDispatchInfo.Capture(e).Throw();
74+
if (clrObject?.inst is ExceptionDispatchInfo storedException)
75+
{
76+
storedException.Throw();
77+
throw storedException.SourceException; // unreachable
78+
}
7779
#endif
80+
if (clrObject?.inst is Exception e)
81+
{
7882
throw e;
7983
}
8084

81-
var result = FromPyErr(pyTypeHandle, pyValueHandle, pyTracebackHandle);
85+
var result = FromPyErr(type, value, traceback);
8286
throw result;
8387
}
8488
finally
8589
{
86-
pyTypeHandle.Dispose();
87-
pyValueHandle.Dispose();
88-
pyTracebackHandle.Dispose();
90+
type.Dispose();
91+
value.Dispose();
92+
traceback.Dispose();
8993
}
9094
}
9195
finally
@@ -108,6 +112,13 @@ static Exception FromPyErr(BorrowedReference typeHandle, BorrowedReference value
108112
return e;
109113
}
110114

115+
#if NETSTANDARD
116+
if (clrObject?.inst is ExceptionDispatchInfo exceptionDispatchInfo)
117+
{
118+
return exceptionDispatchInfo.SourceException;
119+
}
120+
#endif
121+
111122
var type = PyObject.FromNullableReference(typeHandle);
112123
var value = PyObject.FromNullableReference(valueHandle);
113124
var traceback = PyObject.FromNullableReference(tracebackHandle);

0 commit comments

Comments
 (0)