@@ -80,27 +80,30 @@ export function AskAIResults({
8080
8181 const [ conversationId , setConversationId ] = useState < string > ( '' )
8282
83- const handleAICannotAnswer = ( passedConversationId ?: string ) => {
83+ const handleAICannotAnswer = (
84+ passedConversationId ?: string ,
85+ statusCode = 400 ,
86+ uiMessage = t ( 'search.ai.responses.unable_to_answer' ) ,
87+ ) => {
8488 setInitialLoading ( false )
8589 setResponseLoading ( false )
8690 setAICouldNotAnswer ( true )
87- const cannedResponse = t ( 'search.ai.unable_to_answer' )
8891 sendAISearchResultEvent ( {
8992 sources : [ ] ,
90- message : cannedResponse ,
93+ message : uiMessage ,
9194 eventGroupId : askAIEventGroupId . current ,
9295 couldNotAnswer : true ,
93- status : 400 ,
96+ status : statusCode ,
9497 connectedEventId : passedConversationId || conversationId ,
9598 } )
96- setMessage ( cannedResponse )
97- setAnnouncement ( cannedResponse )
99+ setMessage ( uiMessage )
100+ setAnnouncement ( uiMessage )
98101 setReferences ( [ ] )
99102 setItem (
100103 query ,
101104 {
102105 query,
103- message : cannedResponse ,
106+ message : uiMessage ,
104107 sources : [ ] ,
105108 aiCouldNotAnswer : true ,
106109 connectedEventId : passedConversationId || conversationId ,
@@ -158,17 +161,44 @@ export function AskAIResults({
158161 try {
159162 const response = await executeAISearch ( router , version , query , debug )
160163 if ( ! response . ok ) {
161- console . error (
162- `Failed to fetch search results.\nStatus ${ response . status } \n${ response . statusText } ` ,
163- )
164- sendAISearchResultEvent ( {
165- sources : [ ] ,
166- message : '' ,
167- eventGroupId : askAIEventGroupId . current ,
168- couldNotAnswer : false ,
169- status : response . status ,
170- } )
171- return setAISearchError ( )
164+ // If there is JSON and the `upstreamStatus` key, the error is from the upstream sever (CSE)
165+ let responseJson
166+ try {
167+ responseJson = await response . json ( )
168+ } catch ( error ) {
169+ console . error ( 'Failed to parse JSON:' , error )
170+ }
171+ const upstreamStatus = responseJson ?. upstreamStatus
172+ // If there is no upstream status, the error is either on our end or a 500 from CSE, so we can show the error
173+ if ( ! upstreamStatus ) {
174+ console . error (
175+ `Failed to fetch search results.\nStatus ${ response . status } \n${ response . statusText } ` ,
176+ )
177+ sendAISearchResultEvent ( {
178+ sources : [ ] ,
179+ message : '' ,
180+ eventGroupId : askAIEventGroupId . current ,
181+ couldNotAnswer : false ,
182+ status : response . status ,
183+ } )
184+ return setAISearchError ( )
185+ // Query invalid - either sensitive question or spam
186+ } else if ( upstreamStatus === 400 || upstreamStatus === 422 ) {
187+ return handleAICannotAnswer ( '' , upstreamStatus , t ( 'search.ai.responses.invalid_query' ) )
188+ // Query too large
189+ } else if ( upstreamStatus === 413 ) {
190+ return handleAICannotAnswer (
191+ '' ,
192+ upstreamStatus ,
193+ t ( 'search.ai.responses.query_too_large' ) ,
194+ )
195+ } else if ( upstreamStatus === 429 ) {
196+ return handleAICannotAnswer (
197+ '' ,
198+ upstreamStatus ,
199+ t ( 'search.ai.responses.asked_too_many_times' ) ,
200+ )
201+ }
172202 } else {
173203 setAISearchError ( false )
174204 }
@@ -211,7 +241,7 @@ export function AskAIResults({
211241 return
212242 }
213243 } catch ( e ) {
214- console . error (
244+ console . warn (
215245 'Failed to parse JSON:' ,
216246 e ,
217247 'Line:' ,
@@ -228,7 +258,7 @@ export function AskAIResults({
228258 setConversationId ( parsedLine . conversation_id )
229259 } else if ( parsedLine . chunkType === 'NO_CONTENT_SIGNAL' ) {
230260 // Serve canned response. A question that cannot be answered was asked
231- handleAICannotAnswer ( conversationIdBuffer )
261+ handleAICannotAnswer ( conversationIdBuffer , 200 )
232262 } else if ( parsedLine . chunkType === 'SOURCES' ) {
233263 if ( ! isCancelled ) {
234264 sourcesBuffer = sourcesBuffer . concat ( parsedLine . sources )
@@ -242,7 +272,11 @@ export function AskAIResults({
242272 }
243273 } else if ( parsedLine . chunkType === 'INPUT_CONTENT_FILTER' ) {
244274 // Serve canned response. A spam question was asked
245- handleAICannotAnswer ( conversationIdBuffer )
275+ handleAICannotAnswer (
276+ conversationIdBuffer ,
277+ 200 ,
278+ t ( 'search.ai.responses.invalid_query' ) ,
279+ )
246280 }
247281 if ( ! isCancelled ) {
248282 setAnnouncement ( 'Copilot Response Loading...' )
0 commit comments