Skip to content

Conversation

@Kingshuk-Microsoft
Copy link
Contributor

This pull request introduces robust error handling and user feedback mechanisms throughout the orchestration and plan approval workflow, ensuring that network and backend errors are communicated clearly to users and do not cause unexpected UI or backend failures.

Error message handling and display:

  • Implemented a standardized error message formatter and updated the UI to ignore incoming WebSocket messages (plan approval, agent streaming, clarification, tool, and final result) when a network error is detected, preventing confusing or misleading UI states.

These changes collectively make the orchestration workflow more resilient to errors and improve the user experience by providing clear feedback when issues arise.

Purpose

Handling exceptions and showing error messages.

Does this introduce a breaking change?

  • Yes
  • No

How to Test

  • Get the code

What to Check

Basically, when any exceptions occurred, it shouldn't go to a hang state, rather shows a message to user. Few scenarios with screenshots are given.

Verify that the following are valid
Scenario 1: Deleted the agents from foundry and clicked “Approve Task Plan” :
image

Scenario 2: Disconnected wifi
image

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request enhances error handling and user feedback mechanisms throughout the orchestration and plan approval workflow. The changes ensure that network and backend errors are communicated clearly to users and prevent unexpected UI failures.

Key changes:

  • Added standardized error message handling via WebSocket with a new ERROR_MESSAGE message type
  • Implemented network error detection in the frontend to prevent processing of messages when disconnected
  • Added comprehensive exception handling in backend orchestration and API endpoints with user-friendly error messages

Reviewed changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
src/mcp_server/uv.lock Updated fastmcp from 2.11.3 to 2.13.0 and added new dependencies for key-value storage
src/frontend/src/services/WebSocketService.tsx Added ERROR_MESSAGE event handling and emission
src/frontend/src/pages/PlanPage.tsx Implemented network error state, message filtering, timeout handling, and error display UI
src/frontend/src/models/enums.tsx Added ERROR_MESSAGE and SYSTEM_AGENT enum values
src/frontend/src/components/content/PlanChat.tsx Added networkError prop to conditionally render processing spinner
src/backend/v3/orchestration/orchestration_manager.py Added exception handling with specific error types and WebSocket error message delivery
src/backend/v3/models/messages.py Added ERROR_MESSAGE to WebsocketMessageType enum
src/backend/v3/api/router.py Added error handling in plan_approval endpoint with WebSocket error notifications
Comments suppressed due to low confidence (1)

src/frontend/src/pages/PlanPage.tsx:685

  • The useCallback is missing networkError in its dependency array, which means the callback will have a stale closure over the networkError state. This will cause the condition if (!networkError) on line 665 to always use the initial value of networkError rather than the current value. Add networkError to the dependency array.
    const handleApprovePlan = useCallback(async () => {
        if (!planApprovalRequest) return;

        setIsProcessing(true);
        setShowProcessingMessage(true);
        setProcessingApproval(true);
        let id = showToast("Submitting Approval", "progress");

        // Start a 10-second timeout
        const timeoutId = setTimeout(() => {
            dismissToast(id);
            setShowProcessingPlanSpinner(false);
            setSubmittingChatDisableInput(false);
            setProcessingApproval(false);
            setNetworkError(true); 
            setIsProcessing(false);
            setShowProcessingMessage(false);
            showToast("Approval timed out. Please check your network and try again.", "error");
        }, 10000); 

        try {
            await apiService.approvePlan({
                m_plan_id: planApprovalRequest.id,
                plan_id: planData?.plan?.id,
                approved: true,
                feedback: 'Plan approved by user'
            });

            clearTimeout(timeoutId);
            dismissToast(id);
            // Only show processing spinner if there's no network error
            if (!networkError) {
                console.log('🔄 [APPROVAL] Setting showProcessingPlanSpinner = true');
                setShowProcessingPlanSpinner(true);
            } else {
                console.log('⚠️ [APPROVAL] Skipping spinner due to network error');
            }
            setShowApprovalButtons(false);
            setIsProcessing(false);
            setShowProcessingMessage(false);

        } catch (error) {
            clearTimeout(timeoutId);
            dismissToast(id);
            showToast("Failed to submit approval", "error");
            console.error('❌ Failed to approve plan:', error);
            setIsProcessing(false);
            setShowProcessingMessage(false);
        } finally {
            setProcessingApproval(false);
        }
    }, [planApprovalRequest, planData, setProcessingApproval]);

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants