Skip to content

Commit 0ebe97e

Browse files
author
tarekgh
committed
Log deferred header flush failures that cannot be surfaced
When the deferred header flush fails after the response future has already been resolved, TrySetException is a no-op and the failure was swallowed silently. Log it as a warning in that case so the failure stays diagnosable, matching the existing event-stream disposal logging.
1 parent 94ff334 commit 0ebe97e

1 file changed

Lines changed: 10 additions & 1 deletion

File tree

src/ModelContextProtocol.Core/Server/StreamableHttpPostTransport.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,13 @@ private async Task DeferredHeaderFlushAsync(CancellationToken cancellationToken)
156156
}
157157
catch (Exception ex)
158158
{
159-
_httpResponseTcs.TrySetException(ex);
159+
// Surface the failure to the awaiting HandlePostAsync when possible. If the response
160+
// future has already been resolved (the response started or completed on another path),
161+
// TrySetException is a no-op, so log here to keep the deferred-flush failure diagnosable.
162+
if (!_httpResponseTcs.TrySetException(ex))
163+
{
164+
LogDeferredHeaderFlushFailed(ex);
165+
}
160166
}
161167
}
162168

@@ -336,4 +342,7 @@ public async ValueTask DisposeAsync()
336342

337343
[LoggerMessage(Level = LogLevel.Warning, Message = "Failed to dispose SSE event stream writer.")]
338344
private partial void LogStoreStreamDisposalFailed(Exception exception);
345+
346+
[LoggerMessage(Level = LogLevel.Warning, Message = "Failed to flush deferred Streamable HTTP response headers.")]
347+
private partial void LogDeferredHeaderFlushFailed(Exception exception);
339348
}

0 commit comments

Comments
 (0)