diff --git a/src/WinRT.Runtime/ExceptionHelpers.cs b/src/WinRT.Runtime/ExceptionHelpers.cs index 0a345467d..6b9dee168 100644 --- a/src/WinRT.Runtime/ExceptionHelpers.cs +++ b/src/WinRT.Runtime/ExceptionHelpers.cs @@ -84,6 +84,25 @@ static void Throw(int hr) } } + // Retrieve restricted error info from thread without removing it, for propagation and debugging (watch, locals, etc) + private static IObjectReference BorrowRestrictedErrorInfo() + { + if (getRestrictedErrorInfo == null) + return null; + + Marshal.ThrowExceptionForHR(getRestrictedErrorInfo(out IntPtr restrictedErrorInfoPtr)); + if (restrictedErrorInfoPtr == IntPtr.Zero) + return null; + + if (setRestrictedErrorInfo != null) + { + setRestrictedErrorInfo(restrictedErrorInfoPtr); + return ObjectReference.FromAbi(restrictedErrorInfoPtr); + } + + return ObjectReference.Attach(ref restrictedErrorInfoPtr); + } + public static Exception GetExceptionForHR(int hr) => hr >= 0 ? null : GetExceptionForHR(hr, true, out _); private static Exception GetExceptionForHR(int hr, bool useGlobalErrorState, out bool restoredExceptionFromGlobalState) @@ -99,15 +118,12 @@ private static Exception GetExceptionForHR(int hr, bool useGlobalErrorState, out string restrictedCapabilitySid = null; bool hasOtherLanguageException = false; - if (useGlobalErrorState && getRestrictedErrorInfo != null) + if (useGlobalErrorState) { - Marshal.ThrowExceptionForHR(getRestrictedErrorInfo(out IntPtr restrictedErrorInfoPtr)); - - if (restrictedErrorInfoPtr != IntPtr.Zero) + using var restrictedErrorInfoRef = BorrowRestrictedErrorInfo(); + if (restrictedErrorInfoRef != null) { - IObjectReference restrictedErrorInfoRef = ObjectReference.Attach(ref restrictedErrorInfoPtr); restrictedErrorInfoToSave = restrictedErrorInfoRef.As(); - ABI.WinRT.Interop.IRestrictedErrorInfo restrictedErrorInfo = new ABI.WinRT.Interop.IRestrictedErrorInfo(restrictedErrorInfoRef); restrictedErrorInfo.GetErrorDetails(out description, out int hrLocal, out restrictedError, out restrictedCapabilitySid); restrictedErrorReference = restrictedErrorInfo.GetReference(); @@ -230,11 +246,13 @@ public static unsafe void SetErrorInfo(Exception ex) public static void ReportUnhandledError(Exception ex) { SetErrorInfo(ex); - if (getRestrictedErrorInfo != null && roReportUnhandledError != null) + if (roReportUnhandledError != null) { - Marshal.ThrowExceptionForHR(getRestrictedErrorInfo(out IntPtr ppRestrictedErrorInfo)); - using var restrictedErrorRef = ObjectReference.Attach(ref ppRestrictedErrorInfo); - roReportUnhandledError(restrictedErrorRef.ThisPtr); + var restrictedErrorInfoRef = BorrowRestrictedErrorInfo(); + if (restrictedErrorInfoRef != null) + { + roReportUnhandledError(restrictedErrorInfoRef.ThisPtr); + } } }