/// <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(); }
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(); }
/// <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 }
// Deserialize the stream into an object graph. internal Object Deserialize(HeaderHandler handler, ISerParser serParser) { InternalST.Soap( this, "Deserialize Entry handler", handler); if (serParser == null) throw new ArgumentNullException("serParser", String.Format(SoapUtil.GetResourceString("ArgumentNull_WithParamName"), serParser)); deserializationSecurityException = null; try { serializationPermission.Demand(); } catch(Exception e ) { deserializationSecurityException = e; } this.handler = handler; isTopObjectSecondPass = false; isHeaderHandlerCalled = false; if (handler != null) IsFakeTopObject = true; m_idGenerator = new ObjectIDGenerator(); m_objectManager = GetObjectManager(); serObjectInfoInit = new SerObjectInfoInit(); objectIdTable.Clear(); objectIds = 0; // Will call back to ParseObject, ParseHeader for each object found serParser.Run(); if (handler != null) { InternalST.Soap( this, "Deserialize Fixup Before Delegate Invoke"); m_objectManager.DoFixups(); // Fixup for headers // Header handler isn't invoked until method name is known from body fake record // Except for SoapFault, in which case it is invoked below if (handlerObject == null) { InternalST.Soap( this, "Deserialize Before SoapFault Delegate Invoke "); handlerObject = handler(newheaders); InternalST.Soap( this, "Deserialize after SoapFault Delegate Invoke"); } // SoapFault creation Create a fake Pr for the handlerObject to use. // Create a member for the fake pr with name __fault; if ((soapFaultId > 0) && (handlerObject != null)) { InternalST.Soap( this, "Deserialize SoapFault "); topStack = new SerStack("Top ParseRecords"); ParseRecord pr = new ParseRecord(); pr.PRparseTypeEnum = InternalParseTypeE.Object; pr.PRobjectPositionEnum = InternalObjectPositionE.Top; pr.PRparseStateEnum = InternalParseStateE.Object; pr.PRname = "Response"; topStack.Push(pr); pr = new ParseRecord(); pr.PRparseTypeEnum = InternalParseTypeE.Member; pr.PRobjectPositionEnum = InternalObjectPositionE.Child; pr.PRmemberTypeEnum = InternalMemberTypeE.Field; pr.PRmemberValueEnum = InternalMemberValueE.Reference; pr.PRparseStateEnum = InternalParseStateE.Member; pr.PRname = "__fault"; pr.PRidRef = soapFaultId; topStack.Push(pr); pr = new ParseRecord(); pr.PRparseTypeEnum = InternalParseTypeE.ObjectEnd; pr.PRobjectPositionEnum = InternalObjectPositionE.Top; pr.PRparseStateEnum = InternalParseStateE.Object; pr.PRname = "Response"; topStack.Push(pr); isTopObjectResolved = false; } } // Resolve fake top object if necessary if (!isTopObjectResolved) { //resolve top object InternalST.Soap( this, "Deserialize TopObject Second Pass"); isTopObjectSecondPass = true; topStack.Reverse(); // The top of the stack now contains the fake record // When it is Parsed, the handler object will be substituted // for it in ParseObject. int topStackLength = topStack.Count(); ParseRecord pr = null; for (int i=0; i<topStackLength; i++) { pr = (ParseRecord)topStack.Pop(); Parse(pr); } } InternalST.Soap( this, "Deserialize Finished Parsing DoFixups"); m_objectManager.DoFixups(); if (topObject == null) throw new SerializationException(SoapUtil.GetResourceString("Serialization_TopObject")); if (topObject is IObjectReference) { topObject = ((IObjectReference)topObject).GetRealObject(m_context); } InternalST.Soap( this, "Deserialize Exit ",topObject); m_objectManager.RaiseDeserializationEvent(); if ((formatterEnums.FEtopObject != null) && (topObject is InternalSoapMessage)) { // Convert InternalSoapMessage to SoapMessage InternalST.Soap( this, "Deserialize SoapMessage Entry "); InternalSoapMessage ismc = (InternalSoapMessage)topObject; ISoapMessage smc = (ISoapMessage)formatterEnums.FEtopObject; smc.MethodName = ismc.methodName; smc.XmlNameSpace = ismc.xmlNameSpace; smc.ParamNames = ismc.paramNames; smc.ParamValues = ismc.paramValues; smc.Headers = headers; topObject = smc; isTopObjectResolved = true; InternalST.Soap( this, "Deserialize SoapMessage Exit topObject ",topObject," method name ",smc.MethodName); } return topObject; }