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,
};