Skip to content

fix: report runAction failures in desktop app instead of failing silently - #4518

Open
praisonai-triage-agent[bot] wants to merge 1 commit into
mainfrom
claude/issue-4502-20260827-1346
Open

fix: report runAction failures in desktop app instead of failing silently#4518
praisonai-triage-agent[bot] wants to merge 1 commit into
mainfrom
claude/issue-4502-20260827-1346

Conversation

@praisonai-triage-agent

Copy link
Copy Markdown
Contributor

Fixes #4502

Problem

In the desktop app's Settings panel, every runAction branch was a bare await fetch(...), and b.onclick = () => runAction(def) discarded the returned promise. When the engine was unreachable (restart/crash with Settings open β€” the same panel that restarts the engine), the fetch rejected and the click resolved into silence. Worst on Export, the app's only backup path: navigator.clipboard.writeText was never reached, no toast appeared, and the user could paste stale clipboard content into a file believing it was a backup.

Fix (src/praisonai-desktop/ui/index.html)

  • Split runAction into an outer wrapper that try/catch-es and surfaces failures via toast('That did not run: …'), and runActionInner holding the existing branch logic (unchanged behaviour on success).
  • Export now checks if(!r.ok) throw on each fetch (a 500 does not reject), so the clipboard is written only on success β€” a failed export can no longer masquerade as a backup.

Test (frontend/tests/engine-down.test.mjs)

Added a case: with the engine stub throwing a network error, calling the export action asserts (a) navigator.clipboard.writeText was not called with stale content, and (b) an error toast is visible. All 6 tests in the suite pass; buttons and settings-effects suites show no regressions.

Generated with Claude Code

…ntly (fixes #4502)

Wrap the settings runAction body in runActionInner and catch failures with
a toast, so Export/Check for updates/MCP no longer resolve into silence when
the engine is unreachable. Export additionally throws on non-ok responses so a
500 cannot slip past, and the clipboard is only written on success -- a failed
export can no longer masquerade as a backup via a stale paste.

Co-authored-by: MervinPraison <MervinPraison@users.noreply.github.com>
@praisonai-triage-agent

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@praisonai-triage-agent

Copy link
Copy Markdown
Contributor Author

/review

@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more β†’

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account β†’

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us β†’

@greptile-apps

greptile-apps Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR makes desktop Settings actions report rejected operations instead of silently discarding them.

  • Moves existing action branches into a caught runActionInner execution path.
  • Validates both conversation-list and conversation-detail HTTP responses before writing an export to the clipboard.
  • Adds an engine-unreachable export test that verifies no clipboard write occurs and an error toast appears.

Confidence Score: 5/5

The PR appears safe to merge, with no actionable changed-code defects identified.

The wrapper preserves successful action behavior while catching previously discarded failures, and export now writes to the clipboard only after all required HTTP responses succeed.

Important Files Changed

Filename Overview
src/praisonai-desktop/ui/index.html Adds centralized action error reporting and prevents failed or partial HTTP exports from being presented as successful clipboard backups.
src/praisonai-desktop/frontend/tests/engine-down.test.mjs Adds coverage proving an unreachable engine produces an error toast without modifying the clipboard.

Sequence Diagram

sequenceDiagram
  actor User
  participant UI as Desktop Settings
  participant Engine
  participant Clipboard
  User->>UI: Select Export
  UI->>Engine: GET /chats
  alt Request fails or response is not OK
    UI-->>User: Show failure toast
  else Conversation list succeeds
    loop Each conversation
      UI->>Engine: GET /chats/:id
    end
    alt Any detail request fails
      UI-->>User: Show failure toast
    else All details succeed
      UI->>Clipboard: Write complete export
      UI-->>User: Show success toast
    end
  end
Loading

Reviews (1): Last reviewed commit: "fix: report runAction failures in deskto..." | Re-trigger Greptile

@MervinPraison MervinPraison added pipeline/blocked:ci Blocked: CI not green on HEAD pipeline/blocked:no-final Blocked: no FINAL @claude trigger yet pipeline/final-claude-pending Reviews done; waiting for FINAL @claude labels Aug 27, 2026
@MervinPraison

Copy link
Copy Markdown
Owner

@claude You are the FINAL architecture reviewer. If the branch is under MervinPraison/PraisonAI (not a fork), you are able to make modifications to this branch and push directly. SCOPE: Review changes in this PR. Python SDK: praisonaiagents, praisonai. TypeScript SDK: src/praisonai-ts/. Do NOT modify src/praisonai-rust. Read ALL comments above from Gemini, Qodo, CodeRabbit, and Copilot carefully before responding.

Phase 1: Review per AGENTS.md

  1. Protocol-driven: check heavy implementations vs core SDK
  2. Backward compatible: ensure zero feature regressions
  3. Performance: no hot-path regressions
  4. SDK value: review in depth whether the change genuinely adds value to the SDK β€” never add features for the sake of adding them. It must strengthen the SDK (simpler, more user-friendly, robust, world-class, secure). If it does not clearly add value, request changes or recommend rejecting/closing rather than merging scope creep
  5. Do not bloat the Agent class with additional params β€” only if absolutely required; we already support many params.
  6. Repo routing: agent-callable tools β†’ PraisonAI-Tools; lifecycle plugins β†’ PraisonAI-Plugins; optional sandbox backends β†’ PraisonAI-Plugins (praisonai.sandbox entry point) β€” request changes if wrongly added to praisonaiagents/

Phase 2: FIX Valid Issues
7. For any VALID bugs or architectural flaws found by Gemini, CodeRabbit, Qodo, Copilot, or any other reviewer: implement the fix
8. Also independently identify and fix any gaps or issues you find in the changed code β€” do not rely only on prior reviewer feedback
9. Push all code fixes directly to THIS branch (do NOT create a new PR)
10. Comment a summary of exact files modified and what you skipped

Phase 3: Final Verdict
11. If all issues are resolved, approve the PR / close the Issue
12. If blocking issues remain, request changes / leave clear action items

@MervinPraison MervinPraison added pipeline/awaiting-merge-gate FINAL done; waiting for merge gate / CI pipeline/blocked:cooldown Blocked: post-push or @claude cooldown and removed pipeline/final-claude-pending Reviews done; waiting for FINAL @claude pipeline/blocked:no-final Blocked: no FINAL @claude trigger yet labels Aug 27, 2026
@praisonai-triage-agent

praisonai-triage-agent Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor Author

Claude finished @MervinPraison's task β€”β€” View job


Final Architecture Review β€” PR #4518

  • Read guidelines / scope
  • Review changed files (index.html, engine-down.test.mjs)
  • Assess prior reviewer feedback (Greptile βœ… 5/5, Qodo paused)
  • Independently identify gaps/bugs
  • Run tests
  • Fix valid issues β€” none required
  • Final verdict

Verdict: βœ… Approve β€” no changes needed

Scope: Desktop app UI only (src/praisonai-desktop). No Python (praisonaiagents/praisonai) or TS SDK (src/praisonai-ts) surface touched, so AGENTS.md core/wrapper/plugins routing and the Agent-class-bloat rules do not apply. This is a minimal, well-targeted bug fix β€” no scope creep, no new params, no new deps.

Phase 1 checks

  • Backward compatible: βœ… Success paths in runActionInner are byte-for-byte the old branch logic; only failure handling is added.
  • Correctness of the fix: βœ… The real defect was b.onclick = () => runAction(def) discarding a rejected promise. The outer runAction now try/catches and surfaces toast('That did not run: …'). Export now checks if(!r.ok) throw on both /chats and each /chats/:id, so navigator.clipboard.writeText runs only after every fetch succeeds β€” a failed/partial export can no longer masquerade as a backup (index.html:1901‑1924).
  • Performance: βœ… No hot-path impact (settings actions are user-initiated, one-shot).

Independent verification (things I checked beyond the reviewers)

  1. Does window.runAction(...) in the test actually hit the real function? The test at engine-down.test.mjs:100 calls window.runAction, but runAction is a top-level declaration, not explicitly assigned to window (unlike window.dataFolderPath). I probed JSDOM directly and confirmed typeof window.runAction === 'function' (JSDOM's classic-script global scope exposes top-level async function declarations on the global object). So the test genuinely exercises production code β€” not a false pass. Note: this relies on JSDOM/global-scope semantics; it is not a window. assignment. It works, so I'm not changing it, but it's the one slightly fragile seam here.
  2. Nested runAction calls in the mcp branch (toggle/remove/add re-invoke runAction(def)) are now also caught β€” a strict improvement, no regression.
  3. Export !r.ok guard β€” correct: a 500 resolves rather than rejects, so the explicit throw is what stops a stale-clipboard "backup".

Tests run locally

  • engine-down.test.mjs: 6/6 pass
  • buttons.test.mjs + settings-effects.test.mjs: 42/42 pass β€” no regressions.

Files modified by me: none. Skipped: no code fixes β€” no valid blocking issues from any reviewer or from my own pass; the PR is correct, minimal, and tested.
Β· claude/issue-4502-20260827-1346

@praisonai-triage-agent praisonai-triage-agent Bot added pipeline/merge-ready Eligible for merge gate auto-merge and removed pipeline/awaiting-merge-gate FINAL done; waiting for merge gate / CI pipeline/blocked:ci Blocked: CI not green on HEAD pipeline/blocked:cooldown Blocked: post-push or @claude cooldown labels Aug 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pipeline/merge-ready Eligible for merge gate auto-merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

desktop: runAction has no error handling β€” Export, Check for updates and MCP are silently inert when the engine is unreachable

1 participant