private static string GenerateErrorMessage(SessionFault sessionFault, string defaultMessage) { string message = SR.ResourceManager.GetString(SOAFaultCode.GetFaultCodeName(sessionFault.Code), CultureInfo.CurrentCulture); if (message != null) { if (sessionFault.Context == null || sessionFault.Context.Length == 0) { return(message); } else { object[] objArr = new object[sessionFault.Context.Length]; for (int i = 0; i < objArr.Length; i++) { objArr[i] = sessionFault.Context[i]; } return(String.Format(CultureInfo.CurrentCulture, message, objArr)); } } else { return(defaultMessage); } }
/// <summary> /// Generate fault message for a request message. /// </summary> /// <param name="requestMsg">request message</param> /// <returns>generated fault message</returns> private static Message GenerateFaultMessage(Message requestMsg) { MessageVersion version = requestMsg.Headers.MessageVersion; SessionFault sessionFault = new SessionFault(SOAFaultCode.Service_InitializeFailed, StringTable.FailedToInitializeServiceHost); FaultReason faultReason = new FaultReason(StringTable.FailedToInitializeServiceHost); FaultCode faultCode = FaultCode.CreateReceiverFaultCode("ServiceHostInitializationFailed", Constant.HpcHeaderNS); FaultException faultException = new FaultException <SessionFault>(sessionFault, faultReason, faultCode, SessionFault.Action); MessageFault fault = faultException.CreateMessageFault(); Message faultMessage = Message.CreateMessage(version, fault, faultException.Action); faultMessage.Headers.RelatesTo = requestMsg.Headers.MessageId; return(faultMessage); }
/// <summary> /// convert the broker queue exceptioni to the fault exception. /// </summary> /// <param name="e">the broker queue exception.</param> /// <returns>the converted fault exception.</returns> public static FaultException <SessionFault> ConvertBrokerQueueExceptionToFaultException(BrokerQueueException e) { FaultException <SessionFault> faultException = null; if (e != null) { string reason = null; SessionFault fault = null; string exceptionDetail = FetchExceptionDetails(e); switch ((BrokerQueueErrorCode)e.ErrorCode) { case BrokerQueueErrorCode.E_BQ_PERSIST_STORAGE_NOTAVAILABLE: fault = new SessionFault(SOAFaultCode.StorageServiceNotAvailble, SR.StorageServiceNotAvailble); reason = SR.StorageServiceNotAvailble; break; case BrokerQueueErrorCode.E_BQ_PERSIST_STORAGE_INSUFFICIENT: fault = new SessionFault(SOAFaultCode.StorageSpaceNotSufficient, SR.StorageSpaceNotSufficient); reason = SR.StorageSpaceNotSufficient; break; case BrokerQueueErrorCode.E_BQ_PERSIST_STORAGE_FAIL: fault = new SessionFault(SOAFaultCode.StorageFailure, SR.StorageFailure, exceptionDetail); reason = String.Format(CultureInfo.CurrentCulture, SR.StorageFailure, exceptionDetail); break; case BrokerQueueErrorCode.E_BQ_STATUS_CLOSED: fault = new SessionFault(SOAFaultCode.StorageClosed, SR.StorageClosed); reason = SR.StorageClosed; break; default: fault = new SessionFault(SOAFaultCode.UnknownError, SR.UnknownError, exceptionDetail); reason = String.Format(CultureInfo.CurrentCulture, SR.UnknownError, exceptionDetail); break; } faultException = new FaultException <SessionFault>(fault, reason); } return(faultException); }
/// <summary> /// Try to parse broker exception from the message /// </summary> /// <param name="messageFault">indicating the message fault</param> /// <param name="action">indicating the action</param> /// <param name="brokerException">output the broker exception</param> /// <returns>returns a value indicating whether successfully parsed out broker exception</returns> private static bool TryParseBrokerException(MessageFault messageFault, string action, out Exception brokerException) { switch (action) { case AuthenticationFailure.Action: AuthenticationFailure af = messageFault.GetDetail <AuthenticationFailure>(); brokerException = new AuthenticationException(String.Format(SR.Broker_AuthenticationFailure, af.UserName)); return(true); case RetryOperationError.Action: RetryOperationError rle = messageFault.GetDetail <RetryOperationError>(); brokerException = new RetryOperationException(String.Format(SR.Broker_RetryLimitExceeded, rle.RetryCount, rle.Reason), rle.Reason); return(true); case SessionFault.Action: SessionFault fault = messageFault.GetDetail <SessionFault>(); brokerException = Utility.TranslateFaultException(new FaultException <SessionFault>(fault, messageFault.Reason)); return(true); default: brokerException = null; return(false); } }
/// <summary> /// Try to convert an instance of WebException into an instance of FaultException[SessionFault] or ArgumentException /// </summary> /// <param name="exception">indicating the instance of WebException to be converted</param> /// <returns> /// returns the generated exception if convertion succeeded, returns the incoming WebException instance if convertion /// failed /// </returns> public static Exception ConvertWebException(WebException exception) { HttpWebResponse response = exception.Response as HttpWebResponse; if (response == null) { return(exception); } using (response) { HpcWebServiceFault serviceFault = null; try { using (XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(response.GetResponseStream(), XmlDictionaryReaderQuotas.Max)) { serviceFault = (HpcWebServiceFault)FaultSerializer.ReadObject(reader); } } catch { if (response.StatusCode == HttpStatusCode.Forbidden) { // Forbidden error may occur when attempt to GetClusterName, the WebException doesn't contain HpcWebServiceFault. // So convert that exception to SessionException return(new AuthenticationException(SR.WebAPI_AccessDenied)); } else { // Swallow exception if the response stream is not a WCF message // Just return the exception immediately return(exception); } } try { if (serviceFault.Code == SOAFaultCode.ArgumentError) { // This is ArgumentException thrown by the server, fetch error message and rebuild the exception return(new ArgumentException(serviceFault.Message)); } else { string[] values; if (serviceFault.Values != null) { values = new string[serviceFault.Values.Length]; int i = 0; foreach (KeyValuePair <string, string> s in serviceFault.Values) { values[i++] = s.Value; } } else { values = new string[0]; } if (response.StatusCode == HttpStatusCode.Forbidden) { return(new AuthenticationException(string.Format(serviceFault.Message, values))); } else { SessionFault sessionFault = new SessionFault(serviceFault.Code, serviceFault.Message, values); return(new FaultException <SessionFault>(sessionFault, serviceFault.Message)); } } } catch { // If the detail is not an instance of SessionFault, just return the exception itself } } return(exception); }
public void HandleServiceInstanceFailure(SessionFault sessionFault) { }
public void BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState) { Guid guid = Guid.Empty; if (correlationState is Guid) { guid = (Guid)correlationState; } // This trace is included in the user trace. ServiceContext.Logger.TraceEvent( TraceEventType.Verbose, 0, "[HpcServiceHost]: Response is sent back. IsFault = {0}", reply.IsFault); RuntimeTraceHelper.TraceEvent( TraceEventType.Verbose, "[HpcServiceHost]: Response {0} is sent back. IsFault = {1}", guid, reply.IsFault); if (this.propagateActivity) { System.Diagnostics.Trace.CorrelationManager.ActivityId = Guid.Empty; } if (this.hostWrapper.EnableMessageLevelPreemption) { // If the message is skipped, reply a fault message to the broker. if (this.hostWrapper.SkippedMessageIds.Contains(guid)) { this.hostWrapper.SkippedMessageIds.Remove(guid); // For Service_Preempted error, reuse SessionFault.reason property to pass "processing message count" to the broker. int messageCount = this.hostWrapper.ProcessingMessageIds.Count; SessionFault fault = new SessionFault(SOAFaultCode.Service_Preempted, messageCount.ToString()); FaultException faultException = new FaultException <SessionFault>(fault, string.Empty, null, SessionFault.Action); reply = GenerateFaultMessage(guid, reply.Headers.MessageVersion, faultException); } else if (this.hostWrapper.ProcessingMessageIds.Contains(guid)) { this.hostWrapper.ProcessingMessageIds.Remove(guid); // The service host receives the cancel event when the request is being processed, so add a header to notice the broker. if (this.hostWrapper.ReceivedCancelEvent) { // Use the header to pass "processing message count" to the broker. int messageCount = this.hostWrapper.ProcessingMessageIds.Count; reply.Headers.Add(MessageHeader.CreateHeader(Constant.MessageHeaderPreemption, Constant.HpcHeaderNS, messageCount)); } } else { // If the message is not in above two lists, the message doesn't come into the invoker. No need to change its response. } } if (this.hostWrapper.AllMessageIds.Contains(guid)) { this.hostWrapper.AllMessageIds.Remove(guid); lock (this.hostWrapper.AllMessageIds.SyncRoot) { if (this.hostWrapper.AllMessageIds.Count == 0) { this.hostWrapper.SerivceHostIdleTimer?.Change(this.hostWrapper.ServiceHostIdleTimeout, Timeout.Infinite); this.hostWrapper.ServiceHangTimer?.Change(Timeout.Infinite, Timeout.Infinite); } else { this.hostWrapper.ServiceHangTimer?.Change(this.hostWrapper.ServiceHangTimeout, Timeout.Infinite); } } } }
/// <summary> /// Create a new instance of the ServiceInstanceFailedEventArgs class /// </summary> /// <param name="sessionFault">session fault that indicates the fail reason</param> public ServiceInstanceFailedEventArgs(SessionFault sessionFault) { this.sessionFaultField = sessionFault; }