diff options
| author | Haris Gušić <[email protected]> | 2025-10-31 22:20:32 +0100 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-10-31 16:20:32 -0500 |
| commit | 9e392f25a671c220b7eb8927673b42de4575adb6 (patch) | |
| tree | 9bb7f1a344f497e6ed79f07ff9f4e47ca411870a | |
| parent | 2cc4e6ad7c10852f328725820fb79ad48a8698b9 (diff) | |
| download | opencode-9e392f25a671c220b7eb8927673b42de4575adb6.tar.gz opencode-9e392f25a671c220b7eb8927673b42de4575adb6.zip | |
feat: Improve error boundary add button to easily create issue in github (#3639)
| -rw-r--r-- | packages/opencode/src/cli/cmd/tui/app.tsx | 51 |
1 files changed, 50 insertions, 1 deletions
diff --git a/packages/opencode/src/cli/cmd/tui/app.tsx b/packages/opencode/src/cli/cmd/tui/app.tsx index cead812fd..1f1f9f63b 100644 --- a/packages/opencode/src/cli/cmd/tui/app.tsx +++ b/packages/opencode/src/cli/cmd/tui/app.tsx @@ -53,7 +53,7 @@ export function tui(input: { render( () => { return ( - <ErrorBoundary fallback={<text>Something went wrong</text>}> + <ErrorBoundary fallback={(error, reset) => <ErrorComponent error={error} reset={reset} onExit={onExit} />}> <ExitProvider onExit={onExit}> <KVProvider> <ToastProvider> @@ -329,3 +329,52 @@ function App() { </box> ) } + +function ErrorComponent(props: { error: Error; reset: () => void, onExit: () => Promise<void> }) { + const term = useTerminalDimensions() + useKeyboard((evt) => { + if (evt.ctrl && evt.name === "c") { + props.onExit() + } + }) + const [copied, setCopied] = createSignal(false) + + const issueURL = new URL("https://github.com/sst/opencode/issues/new?template=bug-report.yml") + + if (props.error.message) { + issueURL.searchParams.set("title", `opentui: fatal: ${props.error.message}`) + } + + if (props.error.stack) { + issueURL.searchParams.set("description", "```\n" + props.error.stack.substring(0, 6000 - issueURL.toString().length) + "...\n```") + } + + const copyIssueURL = () => { + Clipboard.copy(issueURL.toString()).then(() => { setCopied(true) }) + } + + return ( + <box flexDirection="column" gap={1}> + <box flexDirection="row" gap={1} alignItems="center"> + <text attributes={TextAttributes.BOLD}>Please report an issue.</text> + <box onMouseUp={copyIssueURL} backgroundColor="#565f89" padding={1}> + <text attributes={TextAttributes.BOLD}>Copy issue URL (exception info pre-filled)</text> + </box> + {copied() && <text>Successfully copied</text>} + </box> + <box flexDirection="row" gap={2} alignItems="center"> + <text>A fatal error occurred!</text> + <box onMouseUp={props.reset} backgroundColor="#565f89" padding={1}> + <text>Reset TUI</text> + </box> + <box onMouseUp={props.onExit} backgroundColor="#565f89" padding={1}> + <text>Exit</text> + </box> + </box> + <scrollbox height={Math.floor(term().height * 0.7)}> + <text>{props.error.stack}</text> + </scrollbox> + <text>{props.error.message}</text> + </box > + ) +} |
