// TODO: we propagate an unhandled exception during an operation back to the task, should we handle it differently?
 private void BodyFaultCallback(NativeActivityFaultContext context, Exception propagatedException, ActivityInstance propagatedFrom)
 {
     if (!context.GetReceiveRequestSendResponseScopeExecutionProperty().TrySetTaskCompletionSourceException(propagatedException))
         // this will add a WorkflowInstanceAbortedRecord with the reason
         context.Abort(propagatedException);
     else
         // this won't add any WorkflowInstanceAbortedRecord at all
         context.Abort();
     context.HandleFault();
 }
        /// <summary>
        /// Respond to the fault callback, used for all scheduled activities.
        /// </summary>
        /// <param name="context">The activity context.</param>
        /// <param name="exception">An exception which was thrown by the activity.</param>
        /// <param name="instance">The current instance of the activity.</param>
        private void OnOperationFault(NativeActivityFaultContext context, Exception exception, ActivityInstance instance)
        {
            // Mark the fault handled, or else this activity will throw and will not contine after this method returns.
            context.HandleFault();

            // TODO: Make this logging dependent on the operation configuration
            LogBuildError(context, string.Format("AzureAsyncOperation Fault {0} during execution of {1}\r\n{2}", exception.GetType().Name, instance.Activity.GetType().Name, exception.Message));
            LogBuildMessage(context, exception.StackTrace, BuildMessageImportance.High);

            // Cancel the running activity
            context.CancelChild(instance);

            // Notify that an exception has been caught
            // The CompletionCallback will be called because we handled the exception.
            // This makes a better design choice to do any scheduling or further logic there.
            this.AzureActivityExceptionCaught.Set(context, true);
        }
Пример #3
0
        private void OnTryFaulted(NativeActivityFaultContext faultContext, Exception propagatedException, ActivityInstance propagatedFrom)
        {
            // TODO: delete
            // Write event into the log
            // This is necessary here because the trace log won't be available later
            /*var record = new CustomTrackingRecord("OnTryFaulted", System.Diagnostics.TraceLevel.Error)
            {
                Data =
                {
                    { "Exception", propagatedException },
                    { "JobGuid", JobGuid.Get(faultContext) },
                    { "UserGuid", UserGuid.Get(faultContext) },
                }
            };
            faultContext.Track(record);
            */

            // Handle exception
            int r = retries.Get(faultContext);
            retries.Set(faultContext, ++r);

            faultContext.CancelChild(propagatedFrom);
            faultContext.HandleFault();

            // Run the finally block before doing anything else
            if (Finally != null)
            {
                faultContext.ScheduleActivity(this.Finally, OnFinallyComplete, OnFinallyFaulted);
            }
            else
            {
                OnFinallyComplete(faultContext, null);
            }

            // If retry is possible,
            if (r < MaxRetries.Get(faultContext))
            {
                // absorb error
                faultContext.HandleFault();

                faultContext.ScheduleActivity(this.Try, OnTryComplete, OnTryFaulted);
            }
            else
            {
                // fault
                throw propagatedException;
            }
        }