Skip to content

Commit 646335c

Browse files
appleboyclaude
andcommitted
fix(provider): handle write errors in streaming responses
- Capture and return io.WriteString errors in CompletionStream for Anthropic and Gemini providers - Stop writing to the writer after the first error occurs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent ff63576 commit 646335c

File tree

2 files changed

+19
-3
lines changed

2 files changed

+19
-3
lines changed

provider/anthropic/anthropic.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ func (c *Client) CompletionStream(
7474
w io.Writer,
7575
) (*core.Response, error) {
7676
var sb strings.Builder
77+
var writeErr error
7778
resp, err := c.client.CreateMessagesStream(ctx, anthropic.MessagesStreamRequest{
7879
MessagesRequest: anthropic.MessagesRequest{
7980
Model: c.model,
@@ -85,9 +86,11 @@ func (c *Client) CompletionStream(
8586
TopP: convert.ToPtr(c.topP),
8687
},
8788
OnContentBlockDelta: func(data anthropic.MessagesEventContentBlockDeltaData) {
88-
if data.Delta.Text != nil {
89+
if data.Delta.Text != nil && writeErr == nil {
8990
sb.WriteString(*data.Delta.Text)
90-
_, _ = io.WriteString(w, *data.Delta.Text)
91+
if _, err := io.WriteString(w, *data.Delta.Text); err != nil {
92+
writeErr = err
93+
}
9194
}
9295
},
9396
})
@@ -101,6 +104,10 @@ func (c *Client) CompletionStream(
101104
return nil, err
102105
}
103106

107+
if writeErr != nil {
108+
return nil, fmt.Errorf("failed to write streaming response: %w", writeErr)
109+
}
110+
104111
usage := core.Usage{
105112
PromptTokens: resp.Usage.InputTokens,
106113
CompletionTokens: resp.Usage.OutputTokens,

provider/gemini/gemini.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ func (c *Client) CompletionStream(
9191
}
9292

9393
var sb strings.Builder
94+
var writeErr error
9495
usage := core.Usage{}
9596
for resp, err := range c.client.Models.GenerateContentStream(ctx, c.model, data, cfg) {
9697
if err != nil {
@@ -112,12 +113,20 @@ func (c *Client) CompletionStream(
112113
for _, part := range resp.Candidates[0].Content.Parts {
113114
if part.Text != "" {
114115
sb.WriteString(part.Text)
115-
_, _ = io.WriteString(w, part.Text)
116+
if writeErr == nil {
117+
if _, err := io.WriteString(w, part.Text); err != nil {
118+
writeErr = err
119+
}
120+
}
116121
}
117122
}
118123
}
119124
}
120125

126+
if writeErr != nil {
127+
return nil, fmt.Errorf("failed to write streaming response: %w", writeErr)
128+
}
129+
121130
return &core.Response{
122131
Content: sb.String(),
123132
Usage: usage,

0 commit comments

Comments
 (0)