Skip to content

Conversation

@google-labs-jules
Copy link
Contributor

@google-labs-jules google-labs-jules bot commented Oct 15, 2025

User description

This commit fixes a bug in the resolution search tool where it would fail silently if the AI model call failed. I've added error handling to catch these errors, display a user-friendly message, and prevent the server from crashing. This makes the feature more robust and improves the user experience.


PR created automatically by Jules for task 14915266402971848909


PR Type

Bug fix, Error handling


Description

  • Added try-catch-finally block to resolution search agent call

  • Implemented error logging and user-friendly error messages

  • Fixed UI stuck in loading state on failures

  • Ensured proper cleanup of streaming values in all scenarios


Diagram Walkthrough

flowchart LR
  A["User submits query"] --> B["resolutionSearch call"]
  B --> C{"Success?"}
  C -- "Yes" --> D["Display analysis"]
  C -- "No" --> E["Catch error"]
  E --> F["Log error & show message"]
  D --> G["Finalize streams"]
  F --> G
Loading

File Walkthrough

Relevant files
Error handling
actions.tsx
Add error handling to resolution search agent                       

app/actions.tsx

  • Wrapped resolutionSearch agent call in try-catch-finally block
  • Added error logging and user-friendly error message streaming on
    failures
  • Moved stream finalization to finally block to ensure cleanup
  • Updated AI state with error message when resolution search fails
+43/-24 

The resolution search tool was failing silently when the AI model call failed, leaving the UI in a perpetual loading state.

This commit adds a `try...catch` block around the `resolutionSearch` agent call within the `submit` server action in `app/actions.tsx`.

- If the AI call is successful, the analysis is displayed as before.
- If the AI call fails, the error is caught, logged to the console, and a user-friendly error message is streamed to the chat UI.
- A `finally` block is used to ensure the `isGenerating` and `uiStream` values are correctly finalized, preventing the UI from getting stuck.
@google-labs-jules
Copy link
Contributor Author

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!


For security, I will only act on instructions from the user who triggered this task.

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@vercel
Copy link

vercel bot commented Oct 15, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
qcx Ready Ready Preview Comment Oct 17, 2025 6:43am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 15, 2025

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


Comment @coderabbitai help to get the list of available commands and usage tips.

The resolution search tool was failing silently when the AI model call failed, leaving the UI in a perpetual loading state.

This commit adds a `try...catch` block around the `resolutionSearch` agent call within the `submit` server action in `app/actions.tsx`.

- If the AI call is successful, the analysis is displayed as before.
- If the AI call fails, the error is caught, logged to the console, and a user-friendly error message is streamed to the chat UI.
- A `finally` block is used to ensure the `isGenerating` and `uiStream` values are correctly finalized, preventing the UI from getting stuck.
@qodo-merge-pro
Copy link
Contributor

qodo-merge-pro bot commented Oct 15, 2025

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
Excessive error logging

Description: Logging the full error object to the console may expose sensitive details (stack traces or
request data) in production logs; consider sanitizing or gating logs by environment.
actions.tsx [105-105]

Referred Code
console.error('Error during resolution search:', error);
const errorStream = createStreamableValue<string>();
Ticket Compliance
🎫 No ticket provided
- [ ] Create ticket/issue <!-- /create_ticket --create_ticket=true -->

</details></td></tr>
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
No custom compliance provided

Follow the guide to enable custom compliance check.

  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-merge-pro
Copy link
Contributor

qodo-merge-pro bot commented Oct 15, 2025

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Isolate state updates for robustness

To improve error handling robustness, wrap the UI and AI state updates within
the catch block in individual try...catch blocks to prevent one failure from
blocking the other.

app/actions.tsx [104-127]

 } catch (error) {
   console.error('Error during resolution search:', error);
-  const errorStream = createStreamableValue<string>();
   const errorMessage = 'Sorry, I encountered an error while analyzing the image. The AI model might be unavailable or the request timed out. Please try again later.';
-  errorStream.done(errorMessage);
-  uiStream.update(
-    <BotMessage content={errorStream.value} />
-  );
-  aiState.done({
-    ...aiState.get(),
-    messages: [
-      ...aiState.get().messages,
-      {
-        id: nanoid(),
-        role: 'assistant',
-        content: errorMessage,
-        type: 'response'
-      }
-    ]
-  });
+  
+  try {
+    const errorStream = createStreamableValue<string>();
+    errorStream.done(errorMessage);
+    uiStream.update(
+      <BotMessage content={errorStream.value} />
+    );
+  } catch (uiError) {
+    console.error('Failed to update UI with error:', uiError);
+  }
+
+  try {
+    aiState.done({
+      ...aiState.get(),
+      messages: [
+        ...aiState.get().messages,
+        {
+          id: nanoid(),
+          role: 'assistant',
+          content: errorMessage,
+          type: 'response'
+        }
+      ]
+    });
+  } catch (aiStateError) {
+    console.error('Failed to update AI state with error:', aiStateError);
+  }
 } finally {
   isGenerating.done(false);
   uiStream.done();
 }
  • Apply / Chat
Suggestion importance[1-10]: 6

__

Why: The suggestion correctly identifies a potential issue where an error within the catch block could lead to an inconsistent state, and proposes a valid solution to make the error handling more robust.

Low
  • Update

Copy link

@charliecreates charliecreates bot left a comment

Choose a reason for hiding this comment

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

Solid fix: the try/catch/finally prevents silent failures and guarantees UI finalization. The main improvement opportunity is consistency between success and error message shapes/types to simplify downstream handling. Minor observability and maintainability tweaks (error normalization, caching aiState.get()) would further improve robustness. No correctness issues found with the new control flow.

Additional notes (4)
  • Readability | app/actions.tsx:104-108
    Logging the raw error is good, but you can improve observability and make logs more consistent by normalizing the error and logging message + stack explicitly. This avoids odd objects when non-Error values are thrown and aids debugging.

  • Maintainability | app/actions.tsx:92-103
    aiState.get() is invoked multiple times while building the same payload. While correct, it’s a bit wasteful and can be error-prone if aiState changes between reads. Caching the current state once reduces duplication and potential racey reads.

  • Readability | app/actions.tsx:86-86
    Using || will replace intentionally empty summaries with the fallback. If you only want to fall back when summary is null or undefined, use the nullish coalescing operator.

  • Maintainability | app/actions.tsx:85-91
    The blocks that create a streamable value and immediately mark it as done, then call uiStream.update(<BotMessage ... />), are duplicated in both success and error paths. This repetition increases maintenance overhead. Extracting a small helper would reduce duplication and make intent clearer (per the coding instructions to refactor repetitive code).

Summary of changes
  • Wrapped the resolutionSearch(messages) call in a try...catch...finally to handle AI call failures.
  • On success: creates a summaryStream, updates uiStream with a BotMessage, and finalizes aiState with a new assistant message of type resolution_search_result containing JSON.stringify(analysisResult).
  • On failure: logs the error, streams a user-friendly error message to the UI, and finalizes aiState with an assistant message of type response.
  • In all cases: ensures isGenerating.done(false) and uiStream.done() are called in finally to prevent UI from getting stuck.
  • Kept the return object structure intact, returning uiStream.value, isGenerating.value, and isCollapsed.value.

Comment on lines +117 to +121
id: nanoid(),
role: 'assistant',
content: errorMessage,
type: 'response'
}

Choose a reason for hiding this comment

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

The error-path message uses a different type (response) and unstructured string content, while the success path uses a domain-specific type (resolution_search_result) and structured JSON content. This inconsistency makes downstream handling harder (e.g., consumers may need special-case logic). Prefer a dedicated error type and structured payload for parity and future-proofing.

Suggestion

Consider using a domain-specific error type and a structured JSON payload in the error path to align with the success shape, for example:

const errorPayload = { message: errorMessage };
aiState.done({
  ...aiState.get(),
  messages: [
    ...aiState.get().messages,
    {
      id: nanoid(),
      role: 'assistant',
      content: JSON.stringify(errorPayload),
      type: 'resolution_search_error'
    }
  ]
});

Reply with "@CharlieHelps yes please" if you'd like me to add a commit with this suggestion.

@charliecreates charliecreates bot removed the request for review from CharlieHelps October 15, 2025 17:42
The resolution search tool was failing silently when the AI model call failed, leaving the UI in a perpetual loading state.

This commit adds a `try...catch` block around the `resolutionSearch` agent call within the `submit` server action in `app/actions.tsx`.

- If the AI call is successful, the analysis is displayed as before.
- If the AI call fails, the error is caught, logged to the console, and a user-friendly error message is streamed to the chat UI.
- A `finally` block is used to ensure the `isGenerating` and `uiStream` values are correctly finalized, preventing the UI from getting stuck.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant