@@ -190,16 +190,14 @@ func (i *StreamingInterception) ProcessRequest(w http.ResponseWriter, r *http.Re
190190 })
191191
192192 toolCall = nil
193- } else {
193+ } else if stream . Err () == nil {
194194 // When the provider responds with only tool calls (no text content),
195195 // no chunks are relayed to the client, so the stream is not yet
196196 // initiated. Initiate it here so the SSE headers are sent and the
197197 // ping ticker is started, preventing client timeout during tool invocation.
198198 // Only initiate if no stream error, if there's an error, we'll return
199199 // an HTTP error response instead of starting an SSE stream.
200- if stream .Err () == nil {
201- events .InitiateStream (w )
202- }
200+ events .InitiateStream (w )
203201 }
204202 }
205203
@@ -232,43 +230,43 @@ func (i *StreamingInterception) ProcessRequest(w http.ResponseWriter, r *http.Re
232230 })
233231 }
234232
235- if events .IsStreaming () {
236- // Check if the stream encountered any errors.
237- if streamErr := stream .Err (); streamErr != nil {
238- if eventstream .IsUnrecoverableError (streamErr ) {
239- logger .Debug (ctx , "stream terminated" , slog .Error (streamErr ))
240- // We can't reflect an error back if there's a connection error or the request context was canceled.
241- } else if oaiErr := getErrorResponse (streamErr ); oaiErr != nil {
242- logger .Warn (ctx , "openai stream error" , slog .Error (streamErr ))
243- interceptionErr = oaiErr
244- } else {
245- logger .Warn (ctx , "unknown error" , slog .Error (streamErr ))
246- // Unfortunately, the OpenAI SDK does not support parsing errors received in the stream
247- // into known types (i.e. [shared.OverloadedError]).
248- // See https://github.com/openai/openai-go/blob/v2.7.0/packages/ssestream/ssestream.go#L171
249- // All it does is wrap the payload in an error - which is all we can return, currently.
250- interceptionErr = newErrorResponse (xerrors .Errorf ("unknown stream error: %w" , streamErr ))
251- }
252- } else if lastErr != nil {
253- // Otherwise check if any logical errors occurred during processing.
254- logger .Warn (ctx , "stream failed" , slog .Error (lastErr ))
255- interceptionErr = newErrorResponse (xerrors .Errorf ("processing error: %w" , lastErr ))
256- }
257-
258- if interceptionErr != nil {
259- payload , err := i .marshalErr (interceptionErr )
260- if err != nil {
261- logger .Warn (ctx , "failed to marshal error" , slog .Error (err ), slog .F ("error_payload" , slog .F ("%+v" , interceptionErr )))
262- } else if err := events .Send (streamCtx , payload ); err != nil {
263- logger .Warn (ctx , "failed to relay error" , slog .Error (err ), slog .F ("payload" , payload ))
264- }
265- }
266- } else {
233+ if ! events .IsStreaming () {
267234 // response/downstream Stream has not started yet; write error response and exit.
268235 i .writeUpstreamError (w , getErrorResponse (stream .Err ()))
269236 return stream .Err ()
270237 }
271238
239+ // Check if the stream encountered any errors.
240+ if streamErr := stream .Err (); streamErr != nil {
241+ if eventstream .IsUnrecoverableError (streamErr ) {
242+ logger .Debug (ctx , "stream terminated" , slog .Error (streamErr ))
243+ // We can't reflect an error back if there's a connection error or the request context was canceled.
244+ } else if oaiErr := getErrorResponse (streamErr ); oaiErr != nil {
245+ logger .Warn (ctx , "openai stream error" , slog .Error (streamErr ))
246+ interceptionErr = oaiErr
247+ } else {
248+ logger .Warn (ctx , "unknown error" , slog .Error (streamErr ))
249+ // Unfortunately, the OpenAI SDK does not support parsing errors received in the stream
250+ // into known types (i.e. [shared.OverloadedError]).
251+ // See https://github.com/openai/openai-go/blob/v2.7.0/packages/ssestream/ssestream.go#L171
252+ // All it does is wrap the payload in an error - which is all we can return, currently.
253+ interceptionErr = newErrorResponse (xerrors .Errorf ("unknown stream error: %w" , streamErr ))
254+ }
255+ } else if lastErr != nil {
256+ // Otherwise check if any logical errors occurred during processing.
257+ logger .Warn (ctx , "stream failed" , slog .Error (lastErr ))
258+ interceptionErr = newErrorResponse (xerrors .Errorf ("processing error: %w" , lastErr ))
259+ }
260+
261+ if interceptionErr != nil {
262+ payload , err := i .marshalErr (interceptionErr )
263+ if err != nil {
264+ logger .Warn (ctx , "failed to marshal error" , slog .Error (err ), slog .F ("error_payload" , slog .F ("%+v" , interceptionErr )))
265+ } else if err := events .Send (streamCtx , payload ); err != nil {
266+ logger .Warn (ctx , "failed to relay error" , slog .Error (err ), slog .F ("payload" , payload ))
267+ }
268+ }
269+
272270 // No tool call, nothing more to do.
273271 if toolCall == nil {
274272 break
0 commit comments