diff --git a/src/frontend/src/components/content/HomeInput.tsx b/src/frontend/src/components/content/HomeInput.tsx index 1716f3fdd..8ddc34c1a 100644 --- a/src/frontend/src/components/content/HomeInput.tsx +++ b/src/frontend/src/components/content/HomeInput.tsx @@ -126,19 +126,21 @@ const HomeInput: React.FC = ({ errorDetail = error?.response?.data?.detail; } - // Handle RAI validation errors with better UX + // Handle RAI validation errors - just show description as toast if (errorDetail?.error_type === 'RAI_VALIDATION_FAILED') { - setRAIError(errorDetail); + const description = errorDetail.description || + "Your request contains content that doesn't meet our safety guidelines. Please try rephrasing."; + showToast(description, "error"); } else { // Handle other errors with toast messages const errorMessage = errorDetail?.description || errorDetail?.message || error?.response?.data?.message || error?.message || - "Something went wrong"; + "Something went wrong. Please try again."; + showToast(errorMessage, "error"); } - } finally { setInput(""); setSubmitting(false); @@ -195,7 +197,7 @@ const HomeInput: React.FC = ({ {/* Show RAI error if present */} - {raiError && ( + {/* {raiError && ( { @@ -206,7 +208,7 @@ const HomeInput: React.FC = ({ }} onDismiss={() => setRAIError(null)} /> - )} + )} */} div[style*="position: fixed"]:contains('"error_type"'), +body > div[style*="bottom: 0"]:contains('RAI_VALIDATION_FAILED'), +pre:contains('"message":'), +.error-raw, +.json-error { + display: none !important; +} + +/* Hide any pre-formatted JSON that might contain error messages */ +pre { + white-space: pre-wrap; +} + +pre:has-text('error_type'), +pre:has-text('RAI_VALIDATION_FAILED') { + display: none !important; +} + /* Global Custom Scrollbar */ ::-webkit-scrollbar { overflow-y: auto; /* Ensure scrollable content */ diff --git a/src/frontend/src/services/TaskService.tsx b/src/frontend/src/services/TaskService.tsx index 7f305e30e..5630a8438 100644 --- a/src/frontend/src/services/TaskService.tsx +++ b/src/frontend/src/services/TaskService.tsx @@ -199,15 +199,27 @@ export class TaskService { return await apiService.createPlan(inputTask); } catch (error: any) { // You can customize this logic as needed - let message = "Failed to create plan."; + let message = "Unable to create plan. Please try again."; if (error?.response?.data?.detail) { - message = error.response.data.detail; + const detail = error.response.data.detail; + if (typeof detail === 'string' && detail.includes('RAI_VALIDATION_FAILED')) { + message = "Your request contains content that doesn't meet our safety guidelines. Please rephrase and try again."; + } else if (detail.includes('quota') || detail.includes('limit')) { + message = "Service is currently at capacity. Please try again in a few minutes."; + } else if (detail.includes('unauthorized') || detail.includes('forbidden')) { + message = "You don't have permission to create plans. Please contact your administrator."; + } else { + message = detail; + } } else if (error?.response?.data?.message) { message = error.response.data.message; } else if (error?.message) { - message = error.message; + if (error.message.includes('Network Error') || error.message.includes('fetch')) { + message = "Network error. Please check your connection and try again."; + } else { + message = error.message; + } } - // Throw a new error with a user-friendly message throw new Error(message); } } diff --git a/src/frontend/src/utils/errorUtils.tsx b/src/frontend/src/utils/errorUtils.tsx index ced042c7c..28a51a482 100644 --- a/src/frontend/src/utils/errorUtils.tsx +++ b/src/frontend/src/utils/errorUtils.tsx @@ -8,21 +8,31 @@ export const getErrorMessage = (error: unknown): string => { // Check error message patterns for different types of errors const message = error.message.toLowerCase(); - if (message.includes('400') || message.includes('bad request')) { - return `Bad request: ${error.message}`; + if (message.includes('400') || message.includes('bad request')) { + return 'Invalid request. Please check your input and try again.'; } else if (message.includes('401') || message.includes('unauthorized')) { return 'You are not authorized to perform this action. Please sign in again.'; } else if (message.includes('404') || message.includes('not found')) { - return `Resource not found: ${error.message}`; + return 'The requested resource was not found.'; + } else if (message.includes('429') || message.includes('too many requests')) { + return 'Too many requests. Please wait a moment and try again.'; } else if (message.includes('500') || message.includes('server error')) { - return `Server error: ${error.message}. Please try again later.`; + return 'A server error occurred. Please try again later.'; } else if (message.includes('network') || message.includes('fetch')) { return 'Network error. Please check your connection and try again.'; + } else if (message.includes('timeout')) { + return 'Request timed out. Please try again.'; + } else if (message.includes('quota') || message.includes('limit')) { + return 'Service limit reached. Please try again later.'; } - return error.message; + // Return original message if it's already user-friendly (doesn't contain technical terms) + if (!message.includes('exception') && !message.includes('stack') && + !message.includes('undefined') && !message.includes('null')) { + return error.message; + } } - return 'An unknown error occurred. Please try again.'; + return 'An unexpected error occurred. Please try again.'; }; /**