Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions src/Dapr.Workflow/Client/WorkflowGrpcClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,17 +73,26 @@ public override async Task<string> ScheduleNewWorkflowAsync(string workflowName,
var grpcCallOptions = CreateCallOptions(cancellationToken);
var response = await grpcClient.GetInstanceAsync(request, grpcCallOptions);

if (!response.Exists)
if (response is null)
{
logger.LogGetWorkflowMetadataInstanceNotFound(instanceId);
return null;
}

if (!response.Exists)
{
return null;
}

return ProtoConverters.ToWorkflowMetadata(response.WorkflowState, serializer);
}
catch (RpcException ex) when (ex.StatusCode == StatusCode.NotFound)
{
logger.LogGetWorkflowMetadataInstanceNotFound(ex, instanceId);
return null;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😍

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@barakbbn If there are other issues like this you're experiencing, please don't hesitate to file an issue about it so I can address them too!

@atrauzzi atrauzzi Jun 26, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@barakbbn -- Echoing what Whit said: We would absolutely love to have you (or anyone reading this) open tickets about any pain points or inconsistencies you think exist in the SDK! 🙏

}
catch (Exception ex)
{
logger.LogError(ex, "Error getting workflow metadata for instance '{InstanceId}'", instanceId);
return null;
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/Dapr.Workflow/DaprWorkflowClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ public Task<string> ScheduleNewWorkflowAsync(
/// exist or an error occurs retrieving the metadata.
/// This method never throws.
/// </returns>
public async Task<WorkflowState?> GetWorkflowStateAsync(
public async Task<WorkflowState> GetWorkflowStateAsync(
string instanceId,
bool getInputsAndOutputs = true,
CancellationToken cancellation = default)
Expand All @@ -138,12 +138,12 @@ public Task<string> ScheduleNewWorkflowAsync(
try
{
var metadata = await _innerClient.GetWorkflowMetadataAsync(instanceId, getInputsAndOutputs, cancellation);
return metadata is null ? null : new WorkflowState(metadata);
return new WorkflowState(metadata);
}
catch (RpcException)
{
// If the state doesn't exist, we typically get an `RpcException`, so this wraps this and just returns null
return null;
return new WorkflowState(null);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/Dapr.Workflow/IDaprWorkflowClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ Task<string> ScheduleNewWorkflowAsync(
/// A <see cref="WorkflowMetadata"/> object, or <c>null</c> if the workflow instance does not exist.
/// </returns>
/// <exception cref="ArgumentException">Thrown if <paramref name="instanceId"/> is null or empty.</exception>
Task<WorkflowState?> GetWorkflowStateAsync(
Task<WorkflowState> GetWorkflowStateAsync(
string instanceId,
bool getInputsAndOutputs = true,
CancellationToken cancellation = default);
Expand Down
11 changes: 5 additions & 6 deletions test/Dapr.IntegrationTest.Workflow/PurgeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ public async Task ShouldPurgeCompletedWorkflowInstance()

// Verify workflow state no longer exists after purge
var stateAfterPurge = await daprWorkflowClient.GetWorkflowStateAsync(workflowInstanceId, cancellation: TestContext.Current.CancellationToken);
Assert.Null(stateAfterPurge);
Assert.NotNull(stateAfterPurge);
Assert.False(stateAfterPurge.Exists);
}

[MinimumDaprRuntimeFact("1.17")]
Expand Down Expand Up @@ -153,15 +154,13 @@ public async Task ShouldPurgeTerminatedWorkflowInstance()
Assert.True(purged);

var stateAfterPurge = await daprWorkflowClient.GetWorkflowStateAsync(workflowInstanceId, cancellation: TestContext.Current.CancellationToken);
Assert.Null(stateAfterPurge);
Assert.NotNull(stateAfterPurge);
Assert.False(stateAfterPurge.Exists);
}

private sealed class SimpleWorkflow : Workflow<string, string>
{
public override Task<string> RunAsync(WorkflowContext context, string input)
{
return Task.FromResult($"Processed: {input}");
}
public override Task<string> RunAsync(WorkflowContext context, string input) => Task.FromResult($"Processed: {input}");
}

private sealed class LongRunningWorkflow : Workflow<object?, string>
Expand Down
10 changes: 6 additions & 4 deletions test/Dapr.Workflow.Test/DaprWorkflowClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,20 +85,21 @@ public async Task GetWorkflowStateAsync_ShouldThrowArgumentException_WhenInstanc
}

[Fact]
public async Task GetWorkflowStateAsync_ShouldReturnNull_WhenInnerReturnsNullMetadata()
public async Task GetWorkflowStateAsync_ShouldReflectNotExists_WhenInnerReturnsNullMetadata()
{
var inner = new CapturingWorkflowClient { GetWorkflowMetadataResult = null };
var client = new DaprWorkflowClient(inner);

var state = await client.GetWorkflowStateAsync("missing", cancellation: TestContext.Current.CancellationToken);

Assert.Null(state);
Assert.NotNull(state);
Assert.False(state.Exists);
Assert.Equal("missing", inner.LastGetMetadataInstanceId);
Assert.True(inner.LastGetMetadataGetInputsAndOutputs);
}

[Fact]
public async Task GetWorkflowStateAsync_ShouldReturnNull_WhenInnerThrowsRpcException()
public async Task GetWorkflowStateAsync_ShouldReflectNotExists_WhenInnerThrowsRpcException()
{
var inner = new CapturingWorkflowClient
{
Expand All @@ -108,7 +109,8 @@ public async Task GetWorkflowStateAsync_ShouldReturnNull_WhenInnerThrowsRpcExcep

var state = await client.GetWorkflowStateAsync("i", cancellation: TestContext.Current.CancellationToken);

Assert.Null(state);
Assert.NotNull(state);
Assert.False(state.Exists);
}

[Fact]
Expand Down
Loading