EdgeInteract
Handling Timeout
When no response arrives within timeoutMs, PublishAndWaitAsync() throws InteractionTimeoutException. Every interaction caller must handle this exception — it is not optional.
Catching InteractionTimeoutException
try
{
var response = await _publisher.PublishAndWaitAsync(request, ct);
// Handle response normally
await HandleResponse(response, ct);
}
catch (InteractionTimeoutException ex)
{
_logger.LogWarning(
"Interaction {InteractionId} timed out after {TimeoutMs}ms. CorrelationId: {CorrelationId}",
ex.InteractionId, ex.TimeoutMs, request.CorrelationId);
// Choose a timeout strategy:
await HandleTimeout(request, ex, ct);
}
catch (InteractionBlockedException ex)
{
// The interaction was blocked by a pre-send hook
_logger.LogWarning("Interaction blocked: {Reason}", ex.Message);
throw; // Let the caller know
}
Timeout Strategies
1. Escalate
private async Task HandleTimeout(InteractionRequest original, InteractionTimeoutException ex, CancellationToken ct)
{
var manager = await _orgChart.GetManagerAsync(original.TargetUserId, ct);
if (manager is null) { /* fail */ return; }
// Re-send to manager with a shorter timeout
var escalatedRequest = original with
{
TargetUserId = manager.UserId,
Title = $"[ESCALATED] {original.Title}",
TimeoutMs = 3_600_000, // 1 hour
Metadata = original.Metadata
.Append("escalatedFrom", original.TargetUserId)
.ToDictionary()
};
var response = await _publisher.PublishAndWaitAsync(escalatedRequest, ct);
await HandleResponse(response, ct);
}
2. Auto-Decide
// Auto-approve on timeout (when SLA pressure requires it)
catch (InteractionTimeoutException)
{
await _workflow.ContinueWithApproval(
correlationId: request.CorrelationId,
approvedBy: "system:timeout-auto-approve",
approvedAt: DateTimeOffset.UtcNow,
note: "Auto-approved due to response timeout",
ct: ct);
}
3. Fail the Workflow
// Fail the workflow branch when timeout is unacceptable
catch (InteractionTimeoutException ex)
{
throw new WorkflowExecutionException(
$"HIL interaction {ex.InteractionId} timed out — workflow cannot continue.",
ex);
}
InteractionTimeoutException Properties
| Property | Type | Description |
|---|---|---|
InteractionId | string | The interaction that timed out |
TargetUserId | string | Who was supposed to respond |
TimeoutMs | int | The configured timeout |
TimedOutAt | DateTimeOffset | When the timeout fired |
CorrelationId | string? | The correlation ID from the request |
Never Swallow the Timeout
Do not catch
InteractionTimeoutException and silently continue as if the interaction succeeded. Always make an explicit decision: escalate, auto-decide, or fail. Silent timeouts lead to stalled workflows and confused users.