@@ -15,6 +15,7 @@ import type {
1515} from "ai" ;
1616import type {
1717 TriggerChatHeadersInput ,
18+ TriggerChatOnError ,
1819 TriggerChatReconnectOptions ,
1920 TriggerChatSendMessagesOptions ,
2021 TriggerChatOnTriggeredRun ,
@@ -79,6 +80,7 @@ type TriggerChatTransportCommonOptions<
7980 | TriggerChatTriggerOptionsResolver < UI_MESSAGE > ;
8081 runStore ?: TriggerChatRunStore ;
8182 onTriggeredRun ?: TriggerChatOnTriggeredRun ;
83+ onError ?: TriggerChatOnError ;
8284} ;
8385
8486type TriggerChatTransportMapperRequirement <
@@ -133,6 +135,7 @@ export class TriggerChatTransport<
133135 private readonly previewBranch : string | undefined ;
134136 private readonly requestOptions : ApiRequestOptions | undefined ;
135137 private readonly onTriggeredRun : TriggerChatOnTriggeredRun | undefined ;
138+ private readonly onError : TriggerChatOnError | undefined ;
136139
137140 constructor ( options : TriggerChatTransportOptions < UI_MESSAGE , PAYLOAD > ) {
138141 this . task = options . task ;
@@ -151,6 +154,7 @@ export class TriggerChatTransport<
151154 this . requestOptions
152155 ) ;
153156 this . onTriggeredRun = options . onTriggeredRun ;
157+ this . onError = options . onError ;
154158 }
155159
156160 public async sendMessages (
@@ -180,7 +184,13 @@ export class TriggerChatTransport<
180184 await this . onTriggeredRun ( {
181185 ...runState ,
182186 } ) ;
183- } catch {
187+ } catch ( error ) {
188+ await this . reportError ( {
189+ phase : "onTriggeredRun" ,
190+ chatId : runState . chatId ,
191+ runId : runState . runId ,
192+ error : normalizeError ( error ) ,
193+ } ) ;
184194 // Ignore callback errors so chat streaming can continue.
185195 }
186196 }
@@ -207,10 +217,16 @@ export class TriggerChatTransport<
207217 let stream : ReadableStream < SSEStreamPart < InferUIMessageChunk < UI_MESSAGE > > > ;
208218 try {
209219 stream = await this . fetchRunStream ( runState , undefined , runState . lastEventId ) ;
210- } catch {
220+ } catch ( error ) {
211221 runState . isActive = false ;
212222 await this . runStore . set ( runState ) ;
213223 await this . runStore . delete ( options . chatId ) ;
224+ await this . reportError ( {
225+ phase : "reconnect" ,
226+ chatId : runState . chatId ,
227+ runId : runState . runId ,
228+ error : normalizeError ( error ) ,
229+ } ) ;
214230 return null ;
215231 }
216232
@@ -291,6 +307,12 @@ export class TriggerChatTransport<
291307 runState . isActive = false ;
292308 await this . runStore . set ( runState ) ;
293309 await this . runStore . delete ( chatId ) ;
310+ await this . reportError ( {
311+ phase : "consumeTrackingStream" ,
312+ chatId : runState . chatId ,
313+ runId : runState . runId ,
314+ error : new Error ( "Stream tracking failed" ) ,
315+ } ) ;
294316 }
295317 }
296318 }
@@ -314,6 +336,25 @@ export class TriggerChatTransport<
314336
315337 return `${ normalizedBaseUrl } /realtime/v1/streams/${ encodedRunId } /${ encodedStreamKey } ` ;
316338 }
339+
340+ private async reportError (
341+ event : {
342+ phase : "onTriggeredRun" | "consumeTrackingStream" | "reconnect" ;
343+ chatId : string ;
344+ runId : string ;
345+ error : Error ;
346+ }
347+ ) {
348+ if ( ! this . onError ) {
349+ return ;
350+ }
351+
352+ try {
353+ await this . onError ( event ) ;
354+ } catch {
355+ // Never let error callbacks interfere with transport behavior.
356+ }
357+ }
317358}
318359
319360export function createTriggerChatTransport <
@@ -469,3 +510,11 @@ async function createTriggerTaskOptions(
469510}
470511
471512export type { TriggerChatTaskContext } ;
513+
514+ function normalizeError ( error : unknown ) : Error {
515+ if ( error instanceof Error ) {
516+ return error ;
517+ }
518+
519+ return new Error ( String ( error ) ) ;
520+ }
0 commit comments