@@ -121,7 +121,39 @@ export default function ChatScreen() {
121121 scrollToBottom ( false , 1 ) ;
122122 } , [ currConvId ] ) ;
123123
124- const onChunk : CallbackGeneratedChunk = ( currLeafNodeId ?: Message [ 'id' ] ) => {
124+ // Enhanced onChunk callback with error handling
125+ const onChunk : CallbackGeneratedChunk = ( currLeafNodeId ?: Message [ 'id' ] , error ?: Error ) => {
126+ if ( error ) {
127+ // Handle streaming error - preserve partial content and show error indicator
128+ console . error ( 'Streaming error occurred:' , error ) ;
129+
130+ // Find the current pending message and add error indicator
131+ const currentPendingMsg = pendingMessages [ currConvId ?? '' ] ;
132+ if ( currentPendingMsg && currentPendingMsg . content !== null ) {
133+ // The partial content is already preserved in the pending message
134+ // We just need to add an error indicator to the UI
135+ toast . error ( 'Connection interrupted. Partial response preserved.' , {
136+ duration : 4000 ,
137+ style : {
138+ background : '#fff3cd' ,
139+ color : '#856404' ,
140+ border : '1px solid #ffeaa7' ,
141+ } ,
142+ } ) ;
143+ } else {
144+ // No partial content was generated
145+ toast . error ( 'Connection failed. Please try again.' , {
146+ duration : 4000 ,
147+ style : {
148+ background : '#f8d7da' ,
149+ color : '#721c24' ,
150+ border : '1px solid #f5c6cb' ,
151+ } ,
152+ } ) ;
153+ }
154+ return ;
155+ }
156+
125157 if ( currLeafNodeId ) {
126158 setCurrNodeId ( currLeafNodeId ) ;
127159 }
@@ -139,18 +171,27 @@ export default function ChatScreen() {
139171 setCurrNodeId ( - 1 ) ;
140172 // get the last message node
141173 const lastMsgNodeId = messages . at ( - 1 ) ?. msg . id ?? null ;
142- if (
143- ! ( await sendMessage (
174+
175+ try {
176+ const success = await sendMessage (
144177 currConvId ,
145178 lastMsgNodeId ,
146179 lastInpMsg ,
147180 extraContext . items ,
148181 onChunk
149- ) )
150- ) {
182+ ) ;
183+
184+ if ( ! success ) {
185+ // restore the input message if failed
186+ textarea . setValue ( lastInpMsg ) ;
187+ }
188+ } catch ( error ) {
189+ console . error ( 'Send message error:' , error ) ;
151190 // restore the input message if failed
152191 textarea . setValue ( lastInpMsg ) ;
192+ // The onChunk callback should have already handled the error UI
153193 }
194+
154195 // OK
155196 extraContext . clearItems ( ) ;
156197 } ;
@@ -162,13 +203,20 @@ export default function ChatScreen() {
162203 if ( ! viewingChat ) return ;
163204 setCurrNodeId ( msg . id ) ;
164205 scrollToBottom ( false ) ;
165- await replaceMessageAndGenerate (
166- viewingChat . conv . id ,
167- msg . parent ,
168- content ,
169- msg . extra ,
170- onChunk
171- ) ;
206+
207+ try {
208+ await replaceMessageAndGenerate (
209+ viewingChat . conv . id ,
210+ msg . parent ,
211+ content ,
212+ msg . extra ,
213+ onChunk
214+ ) ;
215+ } catch ( error ) {
216+ console . error ( 'Edit message error:' , error ) ;
217+ // The onChunk callback should handle the error UI
218+ }
219+
172220 setCurrNodeId ( - 1 ) ;
173221 scrollToBottom ( false ) ;
174222 } ;
@@ -177,13 +225,20 @@ export default function ChatScreen() {
177225 if ( ! viewingChat ) return ;
178226 setCurrNodeId ( msg . parent ) ;
179227 scrollToBottom ( false ) ;
180- await replaceMessageAndGenerate (
181- viewingChat . conv . id ,
182- msg . parent ,
183- null ,
184- msg . extra ,
185- onChunk
186- ) ;
228+
229+ try {
230+ await replaceMessageAndGenerate (
231+ viewingChat . conv . id ,
232+ msg . parent ,
233+ null ,
234+ msg . extra ,
235+ onChunk
236+ ) ;
237+ } catch ( error ) {
238+ console . error ( 'Regenerate message error:' , error ) ;
239+ // The onChunk callback should handle the error UI
240+ }
241+
187242 setCurrNodeId ( - 1 ) ;
188243 scrollToBottom ( false ) ;
189244 } ;
@@ -456,4 +511,4 @@ function ChatInput({
456511 </ Dropzone >
457512 </ div >
458513 ) ;
459- }
514+ }
0 commit comments