Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions src/frontend/src/components/content/HomeInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,19 +126,21 @@ const HomeInput: React.FC<HomeInputProps> = ({
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);
Expand Down Expand Up @@ -195,7 +197,7 @@ const HomeInput: React.FC<HomeInputProps> = ({
</div>

{/* Show RAI error if present */}
{raiError && (
{/* {raiError && (
<RAIErrorCard
error={raiError}
onRetry={() => {
Expand All @@ -206,7 +208,7 @@ const HomeInput: React.FC<HomeInputProps> = ({
}}
onDismiss={() => setRAIError(null)}
/>
)}
)} */}

<ChatInput
ref={textareaRef} // forwarding
Expand Down
19 changes: 19 additions & 0 deletions src/frontend/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,25 @@ body, html, :root {
}


/* Hide raw JSON errors */
body > 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 */
Expand Down
20 changes: 16 additions & 4 deletions src/frontend/src/services/TaskService.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand Down
22 changes: 16 additions & 6 deletions src/frontend/src/utils/errorUtils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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.';
};

/**
Expand Down
Loading