// 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); }
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; } }