diff --git a/src/DurableTask.Core/Entities/EventFormat/ResponseMessage.cs b/src/DurableTask.Core/Entities/EventFormat/ResponseMessage.cs index 03de350de..8f78516b5 100644 --- a/src/DurableTask.Core/Entities/EventFormat/ResponseMessage.cs +++ b/src/DurableTask.Core/Entities/EventFormat/ResponseMessage.cs @@ -30,13 +30,13 @@ internal class ResponseMessage : EntityMessage public FailureDetails? FailureDetails { get; set; } [IgnoreDataMember] - public bool IsErrorResult => this.ErrorMessage != null; + public bool IsErrorResult => this.ErrorMessage != null || this.FailureDetails != null; public override string GetShortDescription() { if (this.IsErrorResult) { - return $"[OperationFailed {this.ErrorMessage} {this.FailureDetails}]"; + return $"[OperationFailed {this.FailureDetails?.ErrorMessage ?? this.ErrorMessage}]"; } else if (this.Result == LockAcquisitionCompletion) { diff --git a/src/DurableTask.Core/Entities/OperationFormat/OperationResult.cs b/src/DurableTask.Core/Entities/OperationFormat/OperationResult.cs index 58f26220c..01cc41b11 100644 --- a/src/DurableTask.Core/Entities/OperationFormat/OperationResult.cs +++ b/src/DurableTask.Core/Entities/OperationFormat/OperationResult.cs @@ -23,19 +23,27 @@ public class OperationResult /// /// The serialized result returned by the operation. Can be null, if the operation returned no result. - /// May contain error details, such as a serialized exception, if is not null. + /// May contain error details, such as a serialized exception, if is true. /// public string? Result { get; set; } + /// + /// Whether this operation completed successfully. + /// + public bool IsError + => this.ErrorMessage != null || this.FailureDetails != null; + /// /// If non-null, this string indicates that this operation did not successfully complete. - /// The actual content and its interpretation varies depending on the SDK used. + /// The content and interpretation varies depending on the SDK used. For newer SDKs, + /// we rely on the instead. /// public string? ErrorMessage { get; set; } /// /// A structured language-independent representation of the error. Whether this field is present - /// depends on which SDK is used, and on configuration settings. + /// depends on which SDK is used, and on configuration settings. For newer SDKs, we use + /// this field exclusively when collecting error information. /// public FailureDetails? FailureDetails { get; set; } } diff --git a/src/DurableTask.Core/Logging/LogEvents.cs b/src/DurableTask.Core/Logging/LogEvents.cs index b0fc93ad8..ebf489ded 100644 --- a/src/DurableTask.Core/Logging/LogEvents.cs +++ b/src/DurableTask.Core/Logging/LogEvents.cs @@ -1228,7 +1228,7 @@ public EntityBatchExecuted(EntityBatchRequest request, EntityBatchResult result) this.InstanceId = request.InstanceId; this.OperationCount = request.Operations.Count; this.ResultCount = result.Results.Count; - this.ErrorCount = result.Results.Count(x => x.ErrorMessage != null); + this.ErrorCount = result.Results.Count(x => x.IsError); this.ActionCount = result.Actions.Count; this.EntityStateLength = request.EntityState?.Length ?? 0; } diff --git a/src/DurableTask.Core/TaskEntityDispatcher.cs b/src/DurableTask.Core/TaskEntityDispatcher.cs index dc5303475..549a8cefd 100644 --- a/src/DurableTask.Core/TaskEntityDispatcher.cs +++ b/src/DurableTask.Core/TaskEntityDispatcher.cs @@ -250,12 +250,15 @@ protected async Task OnProcessWorkItemAsync(TaskOrchestrationWorkItem work // if we encountered an error, record it as the result of the operations // so that callers are notified that the operation did not succeed. - if (result.FailureDetails != default(FailureDetails)) + if (result.FailureDetails != null) { OperationResult errorResult = new OperationResult() { - Result = null, + // for older SDKs only + Result = result.FailureDetails.ErrorMessage, ErrorMessage = "entity dispatch failed", + + // for newer SDKs only FailureDetails = result.FailureDetails, };