/// <summary> /// Method for executing a task activity asynchronously /// </summary> /// <param name="context">The task context</param> /// <param name="input">The serialized input</param> /// <returns>Serialized output from the execution</returns> public override async Task <string> RunAsync(TaskContext context, string input) { TInput parameter = default(TInput); var jArray = Utils.ConvertToJArray(input); int parameterCount = jArray.Count; if (parameterCount > 1) { throw new TaskFailureException( "TaskActivity implementation cannot be invoked due to more than expected input parameters. Signature mismatch."); } if (parameterCount == 1) { JToken jToken = jArray[0]; if (jToken is JValue jValue) { parameter = jValue.ToObject <TInput>(); } else { string serializedValue = jToken.ToString(); parameter = DataConverter.Deserialize <TInput>(serializedValue); } } TResult result; try { result = await ExecuteAsync(context, parameter); } catch (Exception e) when(!Utils.IsFatal(e) && !Utils.IsExecutionAborting(e)) { string details = null; FailureDetails failureDetails = null; if (context.ErrorPropagationMode == ErrorPropagationMode.SerializeExceptions) { details = Utils.SerializeCause(e, DataConverter); } else { failureDetails = new FailureDetails(e); } throw new TaskFailureException(e.Message, e, details) .WithFailureDetails(failureDetails); } string serializedResult = DataConverter.Serialize(result); return(serializedResult); }
public void FailOrchestration(Exception failure) { if (failure == null) { throw new ArgumentNullException(nameof(failure)); } string reason = failure.Message; // string details is legacy, FailureDetails is the newer way to share failure information string details = null; FailureDetails failureDetails = null; // correlation CorrelationTraceClient.Propagate( () => { CorrelationTraceClient.TrackException(failure); }); if (failure is OrchestrationFailureException orchestrationFailureException) { if (this.ErrorPropagationMode == ErrorPropagationMode.UseFailureDetails) { // When not serializing exceptions, we instead construct FailureDetails objects failureDetails = orchestrationFailureException.FailureDetails; } else { details = orchestrationFailureException.Details; } } else { if (this.ErrorPropagationMode == ErrorPropagationMode.UseFailureDetails) { failureDetails = new FailureDetails(failure); } else { details = $"Unhandled exception while executing orchestration: {failure}\n\t{failure.StackTrace}"; } } CompleteOrchestration(reason, details, OrchestrationStatus.Failed, failureDetails); }
public void CompleteOrchestration(string result, string details, OrchestrationStatus orchestrationStatus, FailureDetails failureDetails = null) { int id = this.idCounter++; OrchestrationCompleteOrchestratorAction completedOrchestratorAction; if (orchestrationStatus == OrchestrationStatus.Completed && this.continueAsNew != null) { completedOrchestratorAction = this.continueAsNew; } else { if (this.executionCompletedOrTerminated) { return; } this.executionCompletedOrTerminated = true; completedOrchestratorAction = new OrchestrationCompleteOrchestratorAction(); completedOrchestratorAction.Result = result; completedOrchestratorAction.Details = details; completedOrchestratorAction.OrchestrationStatus = orchestrationStatus; completedOrchestratorAction.FailureDetails = failureDetails; } completedOrchestratorAction.Id = id; this.orchestratorActionsMap.Add(id, completedOrchestratorAction); }