private void PreserveStackTrace(Exception exception) { var context = new StreamingContext(StreamingContextStates.CrossAppDomain); var objectManager = new ObjectManager(null, context); var serializationInfo = new SerializationInfo(exception.GetType(), new FormatterConverter()); exception.GetObjectData(serializationInfo, context); objectManager.RegisterObject(exception, 1, serializationInfo); objectManager.DoFixups(); }
/// <remarks> /// Credit to MvcContrib.TestHelper.AssertionException for PreserveStackTrace /// </remarks> private static void PreserveStackTrace(Exception e) { var ctx = new StreamingContext(StreamingContextStates.CrossAppDomain); var mgr = new ObjectManager(null, ctx); var si = new SerializationInfo(e.GetType(), new FormatterConverter()); e.GetObjectData(si, ctx); mgr.RegisterObject(e, 1, si); mgr.DoFixups(); }
/// <summary>Makes sure exception stack trace would not be modify on rethrow.</summary> public static Exception PreserveStackTrace(this Exception exception) { var streamingContext = new StreamingContext(StreamingContextStates.CrossAppDomain); var objectManager = new ObjectManager(null, streamingContext); var serializationInfo = new SerializationInfo(exception.GetType(), new FormatterConverter()); exception.GetObjectData(serializationInfo, streamingContext); objectManager.RegisterObject(exception, 1, serializationInfo); // prepare for SetObjectData objectManager.DoFixups(); // ObjectManager calls SetObjectData return exception; }
public static void PreserveStackTrace(Exception e) { var ctx = new StreamingContext(StreamingContextStates.CrossAppDomain); var mgr = new ObjectManager(null, ctx); var si = new SerializationInfo(e.GetType(), new FormatterConverter()); e.GetObjectData(si, ctx); mgr.RegisterObject(e, 1, si); // prepare for SetObjectData mgr.DoFixups(); // ObjectManager calls SetObjectData // voila, e is unmodified save for _remoteStackTraceString }
public static void PreserveStackTrace(this Exception exception) { try { var context = new StreamingContext(StreamingContextStates.CrossAppDomain); var objectManager = new ObjectManager(null, context); var serializationInfo = new SerializationInfo(exception.GetType(), new FormatterConverter()); exception.GetObjectData(serializationInfo, context); objectManager.RegisterObject(exception, 1, serializationInfo); // prepare for SetObjectData objectManager.DoFixups(); // ObjectManager calls SetObjectData } catch (Exception) { //this is a best effort. if we fail to patch the stack trace just let it go } }
private static void InternalPreserveStackTrace(Exception e) { // check if method is applicable (exception type should have the deserialization constructor) var bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; var constructor = e.GetType().GetConstructor(bindingFlags, null, new[] { typeof(SerializationInfo), typeof(StreamingContext) }, null); if (constructor == null) { return; } var ctx = new StreamingContext(StreamingContextStates.CrossAppDomain); var mgr = new ObjectManager(null, ctx); var si = new SerializationInfo(e.GetType(), new FormatterConverter()); e.GetObjectData(si, ctx); mgr.RegisterObject(e, 1, si); // prepare for SetObjectData mgr.DoFixups(); // ObjectManager calls the deserialization constructor // voila, e is unmodified save for _remoteStackTraceString }
/// <summary> /// Modifies the specified exception's _remoteStackTraceString. I have no idea how this works, but it allows /// for unpacking a re-throwable inner exception from a caught <see cref="TargetInvocationException"/>. /// Read <see cref="http://stackoverflow.com/a/2085364/6560"/> for more information. /// </summary> public static void PreserveStackTrace(this Exception exception) { try { var ctx = new StreamingContext(StreamingContextStates.CrossAppDomain); var mgr = new ObjectManager(null, ctx); var si = new SerializationInfo(exception.GetType(), new FormatterConverter()); exception.GetObjectData(si, ctx); mgr.RegisterObject(exception, 1, si); // prepare for SetObjectData mgr.DoFixups(); // ObjectManager calls SetObjectData // voila, exception is unmodified save for _remoteStackTraceString } catch (Exception ex) { var message = string.Format("This exception was caught while attempting to preserve the stack trace for" + " an exception: {0} - the original exception is passed as the inner exception" + " of this exception. This is most likely caused by the absence of a proper" + " serialization constructor on an exception", ex); throw new ApplicationException(message, exception); } }
/// <summary> /// Causes the original strack trace of the exception to be preserved when it is rethrown /// </summary> /// <param name="ex"></param> private static void PrepareExceptionForRethrow(Exception ex) { var ctx = new StreamingContext(StreamingContextStates.CrossAppDomain); var mgr = new ObjectManager(null, ctx); var si = new SerializationInfo(ex.GetType(), new FormatterConverter()); ex.GetObjectData(si, ctx); mgr.RegisterObject(ex, 1, si); // prepare for SetObjectData mgr.DoFixups(); // ObjectManager calls SetObjectData }