yangdx
commited on
Commit
·
c0ff8f3
1
Parent(s):
dadfdd4
Optimize webui error handling of streaming response
Browse files
lightrag/api/__init__.py
CHANGED
@@ -1 +1 @@
|
|
1 |
-
__api_version__ = "
|
|
|
1 |
+
__api_version__ = "0160"
|
lightrag_webui/src/api/lightrag.ts
CHANGED
@@ -299,12 +299,29 @@ export const queryTextStream = async (
|
|
299 |
});
|
300 |
|
301 |
if (!response.ok) {
|
302 |
-
// Handle
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
303 |
let errorBody = 'Unknown error';
|
304 |
try {
|
305 |
errorBody = await response.text(); // Try to get error details from body
|
306 |
} catch { /* ignore */ }
|
307 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
308 |
}
|
309 |
|
310 |
if (!response.body) {
|
@@ -362,12 +379,81 @@ export const queryTextStream = async (
|
|
362 |
|
363 |
} catch (error) {
|
364 |
const message = errorMessage(error);
|
365 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
366 |
if (onError) {
|
367 |
onError(message);
|
368 |
} else {
|
369 |
-
|
370 |
-
console.error('Unhandled stream error:', message);
|
371 |
}
|
372 |
}
|
373 |
};
|
|
|
299 |
});
|
300 |
|
301 |
if (!response.ok) {
|
302 |
+
// Handle 401 Unauthorized error specifically
|
303 |
+
if (response.status === 401) {
|
304 |
+
// For consistency with axios interceptor, navigate to login page
|
305 |
+
navigationService.navigateToLogin();
|
306 |
+
|
307 |
+
// Create a specific authentication error
|
308 |
+
const authError = new Error('Authentication required');
|
309 |
+
throw authError;
|
310 |
+
}
|
311 |
+
|
312 |
+
// Handle other common HTTP errors with specific messages
|
313 |
let errorBody = 'Unknown error';
|
314 |
try {
|
315 |
errorBody = await response.text(); // Try to get error details from body
|
316 |
} catch { /* ignore */ }
|
317 |
+
|
318 |
+
// Format error message similar to axios interceptor for consistency
|
319 |
+
const url = `${backendBaseUrl}/query/stream`;
|
320 |
+
throw new Error(
|
321 |
+
`${response.status} ${response.statusText}\n${JSON.stringify(
|
322 |
+
{ error: errorBody }
|
323 |
+
)}\n${url}`
|
324 |
+
);
|
325 |
}
|
326 |
|
327 |
if (!response.body) {
|
|
|
379 |
|
380 |
} catch (error) {
|
381 |
const message = errorMessage(error);
|
382 |
+
|
383 |
+
// Check if this is an authentication error
|
384 |
+
if (message === 'Authentication required') {
|
385 |
+
// Already navigated to login page in the response.status === 401 block
|
386 |
+
console.error('Authentication required for stream request');
|
387 |
+
if (onError) {
|
388 |
+
onError('Authentication required');
|
389 |
+
}
|
390 |
+
return; // Exit early, no need for further error handling
|
391 |
+
}
|
392 |
+
|
393 |
+
// Check for specific HTTP error status codes in the error message
|
394 |
+
const statusCodeMatch = message.match(/^(\d{3})\s/);
|
395 |
+
if (statusCodeMatch) {
|
396 |
+
const statusCode = parseInt(statusCodeMatch[1], 10);
|
397 |
+
|
398 |
+
// Handle specific status codes with user-friendly messages
|
399 |
+
let userMessage = message;
|
400 |
+
|
401 |
+
switch (statusCode) {
|
402 |
+
case 403:
|
403 |
+
userMessage = 'You do not have permission to access this resource (403 Forbidden)';
|
404 |
+
console.error('Permission denied for stream request:', message);
|
405 |
+
break;
|
406 |
+
case 404:
|
407 |
+
userMessage = 'The requested resource does not exist (404 Not Found)';
|
408 |
+
console.error('Resource not found for stream request:', message);
|
409 |
+
break;
|
410 |
+
case 429:
|
411 |
+
userMessage = 'Too many requests, please try again later (429 Too Many Requests)';
|
412 |
+
console.error('Rate limited for stream request:', message);
|
413 |
+
break;
|
414 |
+
case 500:
|
415 |
+
case 502:
|
416 |
+
case 503:
|
417 |
+
case 504:
|
418 |
+
userMessage = `Server error, please try again later (${statusCode})`;
|
419 |
+
console.error('Server error for stream request:', message);
|
420 |
+
break;
|
421 |
+
default:
|
422 |
+
console.error('Stream request failed with status code:', statusCode, message);
|
423 |
+
}
|
424 |
+
|
425 |
+
if (onError) {
|
426 |
+
onError(userMessage);
|
427 |
+
}
|
428 |
+
return;
|
429 |
+
}
|
430 |
+
|
431 |
+
// Handle network errors (like connection refused, timeout, etc.)
|
432 |
+
if (message.includes('NetworkError') ||
|
433 |
+
message.includes('Failed to fetch') ||
|
434 |
+
message.includes('Network request failed')) {
|
435 |
+
console.error('Network error for stream request:', message);
|
436 |
+
if (onError) {
|
437 |
+
onError('Network connection error, please check your internet connection');
|
438 |
+
}
|
439 |
+
return;
|
440 |
+
}
|
441 |
+
|
442 |
+
// Handle JSON parsing errors during stream processing
|
443 |
+
if (message.includes('Error parsing') || message.includes('SyntaxError')) {
|
444 |
+
console.error('JSON parsing error in stream:', message);
|
445 |
+
if (onError) {
|
446 |
+
onError('Error processing response data');
|
447 |
+
}
|
448 |
+
return;
|
449 |
+
}
|
450 |
+
|
451 |
+
// Handle other errors
|
452 |
+
console.error('Unhandled stream error:', message);
|
453 |
if (onError) {
|
454 |
onError(message);
|
455 |
} else {
|
456 |
+
console.error('No error handler provided for stream error:', message);
|
|
|
457 |
}
|
458 |
}
|
459 |
};
|