@@ -27,6 +27,7 @@ import { logStore } from '~/lib/stores/logs';
2727import { streamingState } from '~/lib/stores/streaming' ;
2828import { filesToArtifacts } from '~/utils/fileUtils' ;
2929import { supabaseConnection } from '~/lib/stores/supabase' ;
30+ import { ImportErrorModal } from '~/components/ui/ImportErrorModal' ;
3031
3132const toastAnimation = cssTransition ( {
3233 enter : 'animated fadeInRight' ,
@@ -123,6 +124,14 @@ export const ChatImpl = memo(
123124 const [ imageDataList , setImageDataList ] = useState < string [ ] > ( [ ] ) ;
124125 const [ searchParams , setSearchParams ] = useSearchParams ( ) ;
125126 const [ fakeLoading , setFakeLoading ] = useState ( false ) ;
127+ const [ importError , setImportError ] = useState < {
128+ type : 'warning' | 'error' ;
129+ title : string ;
130+ message : string ;
131+ failedFiles ?: string [ ] ;
132+ onRetry ?: ( ) => void ;
133+ onContinue ?: ( ) => void ;
134+ } | null > ( null ) ;
126135 const files = useStore ( workbenchStore . files ) ;
127136 const actionAlert = useStore ( workbenchStore . alert ) ;
128137 const deployAlert = useStore ( workbenchStore . deployAlert ) ;
@@ -327,17 +336,67 @@ export const ChatImpl = memo(
327336
328337 if ( template !== 'blank' ) {
329338 const temResp = await getTemplates ( template , title ) . catch ( ( e ) => {
330- if ( e . message . includes ( 'rate limit' ) ) {
331- toast . warning ( 'Rate limit exceeded. Skipping starter template\n Continuing with blank template' ) ;
339+ // Check for specific error types from selectStarterTemplate.ts
340+ if ( e . message === 'RATE_LIMIT' ) {
341+ setImportError ( {
342+ type : 'error' ,
343+ title : 'Rate Limit Exceeded' ,
344+ message : 'GitHub API rate limit exceeded. Please try again in a few minutes.' ,
345+ } ) ;
346+ } else if ( e . message === 'REPO_NOT_FOUND' ) {
347+ setImportError ( {
348+ type : 'error' ,
349+ title : 'Repository Not Found' ,
350+ message : 'Template repository not found. Using blank template instead.' ,
351+ } ) ;
352+ } else if ( e . message === 'NETWORK_ERROR' ) {
353+ setImportError ( {
354+ type : 'error' ,
355+ title : 'Network Error' ,
356+ message : 'Network error while fetching template. Please check your connection.' ,
357+ } ) ;
332358 } else {
333- toast . warning ( 'Failed to import starter template\n Continuing with blank template' ) ;
359+ setImportError ( {
360+ type : 'error' ,
361+ title : 'Template Fetch Failed' ,
362+ message : 'Failed to fetch template. Please try again.' ,
363+ } ) ;
334364 }
335365
336366 return null ;
337367 } ) ;
338368
339369 if ( temResp ) {
340- const { assistantMessage, userMessage } = temResp ;
370+ const { assistantMessage, userMessage, failedFiles } = temResp ;
371+
372+ // Check for failed files
373+ if ( failedFiles && failedFiles . length > 0 ) {
374+ setImportError ( {
375+ type : 'warning' ,
376+ title : 'Template Partially Imported' ,
377+ message : `${ failedFiles . length } file(s) failed to import due to network errors.` ,
378+ failedFiles : failedFiles . map ( ( f : { path : string } ) => f . path ) ,
379+ onRetry : async ( ) => {
380+ const retryResp = await getTemplates ( template , title ) ;
381+
382+ if ( retryResp && ( ! retryResp . failedFiles || retryResp . failedFiles . length === 0 ) ) {
383+ setImportError ( null ) ;
384+
385+ // Continue with template
386+ } else if ( retryResp && retryResp . failedFiles ) {
387+ // Still have failures, update modal
388+ setImportError ( ( prev ) => ( {
389+ ...prev ! ,
390+ failedFiles : retryResp . failedFiles . map ( ( f : { path : string } ) => f . path ) ,
391+ } ) ) ;
392+ }
393+ } ,
394+ onContinue : ( ) => {
395+ setImportError ( null ) ;
396+ } ,
397+ } ) ;
398+ }
399+
341400 setMessages ( [
342401 {
343402 id : `1-${ new Date ( ) . getTime ( ) } ` ,
@@ -365,10 +424,10 @@ export const ChatImpl = memo(
365424 annotations : [ 'hidden' ] ,
366425 } ,
367426 ] ) ;
427+
368428 reload ( ) ;
369429 setInput ( '' ) ;
370430 Cookies . remove ( PROMPT_COOKIE_KEY ) ;
371-
372431 setUploadedFiles ( [ ] ) ;
373432 setImageDataList ( [ ] ) ;
374433
@@ -505,66 +564,80 @@ export const ChatImpl = memo(
505564 } ;
506565
507566 return (
508- < BaseChat
509- ref = { animationScope }
510- textareaRef = { textareaRef }
511- input = { input }
512- showChat = { showChat }
513- chatStarted = { chatStarted }
514- isStreaming = { isLoading || fakeLoading }
515- onStreamingChange = { ( streaming ) => {
516- streamingState . set ( streaming ) ;
517- } }
518- enhancingPrompt = { enhancingPrompt }
519- promptEnhanced = { promptEnhanced }
520- sendMessage = { sendMessage }
521- model = { model }
522- setModel = { handleModelChange }
523- provider = { provider }
524- setProvider = { handleProviderChange }
525- providerList = { activeProviders }
526- handleInputChange = { ( e ) => {
527- onTextareaChange ( e ) ;
528- debouncedCachePrompt ( e ) ;
529- } }
530- handleStop = { abort }
531- description = { description }
532- importChat = { importChat }
533- exportChat = { exportChat }
534- messages = { messages . map ( ( message , i ) => {
535- if ( message . role === 'user' ) {
536- return message ;
537- }
567+ < >
568+ < BaseChat
569+ ref = { animationScope }
570+ textareaRef = { textareaRef }
571+ input = { input }
572+ showChat = { showChat }
573+ chatStarted = { chatStarted }
574+ isStreaming = { isLoading || fakeLoading }
575+ onStreamingChange = { ( streaming ) => {
576+ streamingState . set ( streaming ) ;
577+ } }
578+ enhancingPrompt = { enhancingPrompt }
579+ promptEnhanced = { promptEnhanced }
580+ sendMessage = { sendMessage }
581+ model = { model }
582+ setModel = { handleModelChange }
583+ provider = { provider }
584+ setProvider = { handleProviderChange }
585+ providerList = { activeProviders }
586+ handleInputChange = { ( e ) => {
587+ onTextareaChange ( e ) ;
588+ debouncedCachePrompt ( e ) ;
589+ } }
590+ handleStop = { abort }
591+ description = { description }
592+ importChat = { importChat }
593+ exportChat = { exportChat }
594+ messages = { messages . map ( ( message , i ) => {
595+ if ( message . role === 'user' ) {
596+ return message ;
597+ }
538598
539- return {
540- ...message ,
541- content : parsedMessages [ i ] || '' ,
542- } ;
543- } ) }
544- enhancePrompt = { ( ) => {
545- enhancePrompt (
546- input ,
547- ( input ) => {
548- setInput ( input ) ;
549- scrollTextArea ( ) ;
550- } ,
551- model ,
552- provider ,
553- apiKeys ,
554- ) ;
555- } }
556- uploadedFiles = { uploadedFiles }
557- setUploadedFiles = { setUploadedFiles }
558- imageDataList = { imageDataList }
559- setImageDataList = { setImageDataList }
560- actionAlert = { actionAlert }
561- clearAlert = { ( ) => workbenchStore . clearAlert ( ) }
562- supabaseAlert = { supabaseAlert }
563- clearSupabaseAlert = { ( ) => workbenchStore . clearSupabaseAlert ( ) }
564- deployAlert = { deployAlert }
565- clearDeployAlert = { ( ) => workbenchStore . clearDeployAlert ( ) }
566- data = { chatData }
567- />
599+ return {
600+ ...message ,
601+ content : parsedMessages [ i ] || '' ,
602+ } ;
603+ } ) }
604+ enhancePrompt = { ( ) => {
605+ enhancePrompt (
606+ input ,
607+ ( input ) => {
608+ setInput ( input ) ;
609+ scrollTextArea ( ) ;
610+ } ,
611+ model ,
612+ provider ,
613+ apiKeys ,
614+ ) ;
615+ } }
616+ uploadedFiles = { uploadedFiles }
617+ setUploadedFiles = { setUploadedFiles }
618+ imageDataList = { imageDataList }
619+ setImageDataList = { setImageDataList }
620+ actionAlert = { actionAlert }
621+ clearAlert = { ( ) => workbenchStore . clearAlert ( ) }
622+ supabaseAlert = { supabaseAlert }
623+ clearSupabaseAlert = { ( ) => workbenchStore . clearSupabaseAlert ( ) }
624+ deployAlert = { deployAlert }
625+ clearDeployAlert = { ( ) => workbenchStore . clearDeployAlert ( ) }
626+ data = { chatData }
627+ />
628+ { importError && (
629+ < ImportErrorModal
630+ isOpen = { Boolean ( importError ) }
631+ type = { importError . type }
632+ title = { importError . title }
633+ message = { importError . message }
634+ failedFiles = { importError . failedFiles }
635+ onRetry = { importError . onRetry }
636+ onContinue = { importError . onContinue }
637+ onClose = { ( ) => setImportError ( null ) }
638+ />
639+ ) }
640+ </ >
568641 ) ;
569642 } ,
570643) ;
0 commit comments