private void SerialiseSystemException(CdrOutputStream targetStream, Exception corbaEx) { // serialize a system exception if (!(corbaEx is AbstractCORBASystemException)) { corbaEx = new UNKNOWN(202, omg.org.CORBA.CompletionStatus.Completed_MayBe); } Serializer ser = m_serFactory.Create(corbaEx.GetType(), Util.AttributeExtCollection.EmptyCollection); ser.Serialize(corbaEx, targetStream); }
/// <summary> /// determines, which exception to return to the client based on /// the called method/attribute and on the Exception thrown. /// Make sure to return only exceptions, which are allowed for the thrower; e.g. /// only those specified in the interface for methods and for attributes only system exceptions. /// </summary> private Exception DetermineExceptionToThrow(Exception thrown, MethodBase thrower) { if (thrown is omg.org.CORBA.AbstractCORBASystemException) { return thrown; // system exceptions are not wrapped or transformed } Exception exceptionToThrow; if ((thrower is MethodInfo) && (!((MethodInfo)thrower).IsSpecialName)) { // is a normal method (i.e. no property accessor, ...) if (ReflectionHelper.IIdlEntityType.IsAssignableFrom(thrower.DeclaringType)) { exceptionToThrow = DetermineIdlExceptionToThrow(thrown, (MethodInfo)thrower); } else { if (ReflectionHelper.IsExceptionInRaiseAttributes(thrown, (MethodInfo)thrower) && (thrown is AbstractUserException)) { exceptionToThrow = thrown; // a .NET method could also use ThrowsIdlException attribute to return non-wrapped exceptions } else { // wrap into generic user exception, because CLS to IDL gen adds this exception to // all methods exceptionToThrow = new GenericUserException(thrown); } } } else if ((thrower is MethodInfo) && (((MethodInfo)thrower).IsSpecialName)) { // is a special method (i.e. a property accessor, ...) exceptionToThrow = new UNKNOWN(190, CompletionStatus.Completed_Yes); } else { // thrower == null means here, that the target method was not determined, // i.e. the request deserialisation was not ok Debug.WriteLine("target method unknown, can't determine what exception client accepts; thrown was: " + thrown); exceptionToThrow = new UNKNOWN(201, CompletionStatus.Completed_No); } return exceptionToThrow; }
/// <summary>serialize the GIOP message body of a repsonse message</summary> /// <param name="requestId">the requestId of the request, this response belongs to</param> internal void SerialiseReply(GiopServerRequest request, CdrOutputStream targetStream, GiopVersion version, GiopConnectionDesc conDesc) { Trace.WriteLine("serializing response for method: " + request.GetRequestedMethodNameInternal()); try { bool isExceptionReply = request.IsExceptionReply; Exception exceptionToSend = null; try { request.SetRequestPICurrentFromThreadScopeCurrent(); // copy from thread scope picurrent after processing request by servant // reply interception point if (!request.IsExceptionReply) { request.InterceptSendReply(); } else { exceptionToSend = request.InterceptSendException(request.IdlException); } } catch (Exception ex) { // update the reply with the exception from interception layer isExceptionReply = true; if (SerialiseAsSystemException(ex)) { exceptionToSend = ex; } else { exceptionToSend = new UNKNOWN(300, CompletionStatus.Completed_MayBe); } } ServiceContextList cntxColl = request.ResponseServiceContext; SetCodeSet(targetStream, conDesc); if (version.IsBeforeGiop1_2()) { // for GIOP 1.0 / 1.1 SerialiseContext(targetStream, cntxColl); // serialize the context } targetStream.WriteULong(request.RequestId); if (!isExceptionReply) { Trace.WriteLine("sending normal response to client"); targetStream.WriteULong(0); // reply status ok if (!version.IsBeforeGiop1_2()) { // for GIOP 1.2 and later, service context is here SerialiseContext(targetStream, cntxColl); // serialize the context } // serialize a response to a successful request SerialiseResponseOk(targetStream, request, version); Trace.WriteLine("reply body serialised"); } else { Trace.WriteLine("excpetion to send to client: " + exceptionToSend.GetType()); if (SerialiseAsSystemException(exceptionToSend)) { targetStream.WriteULong(2); // system exception } else if (SerialiseAsUserException(exceptionToSend)) { targetStream.WriteULong(1); // user exception } else { // should not occur targetStream.WriteULong(2); exceptionToSend = new INTERNAL(204, CompletionStatus.Completed_Yes); } if (!version.IsBeforeGiop1_2()) { // for GIOP 1.2 and later, service context is here SerialiseContext(targetStream, cntxColl); // serialize the context } AlignBodyIfNeeded(targetStream, version); if (SerialiseAsSystemException(exceptionToSend)) { SerialiseSystemException(targetStream, exceptionToSend); } else { SerialiseUserException(targetStream, (AbstractUserException)exceptionToSend); } Trace.WriteLine("exception reply serialised"); } } finally { request.ClearThreadScopePICurrent(); // no longer needed, clear afterwards to prevent access to stale data during next requests } }