mirror of
https://github.com/OpenRouterTeam/spawn.git
synced 2026-04-28 11:59:29 +00:00
refactor: replace indiscriminate try/catch with guarded Result helpers (#2477)
Add tryCatchIf/asyncTryCatchIf with error predicates (isFileError, isNetworkError, isOperationalError) so operational errors are handled explicitly while programming bugs (TypeError, ReferenceError) propagate and crash visibly instead of being silently swallowed. Transforms ~40 try/catch blocks across 14 files: - File I/O (manifest cache, config loading, history) → tryCatchIf(isFileError) - Network/fetch (API calls, version checks, OAuth) → asyncTryCatchIf(isNetworkError) - SSH/subprocess (agent setup, tunnel) → asyncTryCatchIf(isOperationalError) - API retry loops (DO, Hetzner) → guard retries with isNetworkError Intentionally keeps ~85 try/catch blocks as-is (cleanup/finally, retry loops, user-facing error handlers, catch-classify-rethrow patterns). Co-authored-by: lab <6723574+louisgv@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7444c3bbc6
commit
3fd17e3d1d
15 changed files with 645 additions and 163 deletions
|
|
@ -11,6 +11,7 @@ import { offerGithubAuth, wrapSshCall } from "./agent-setup";
|
|||
import { tryTarballInstall } from "./agent-tarball";
|
||||
import { generateEnvConfig } from "./agents";
|
||||
import { getOrPromptApiKey } from "./oauth";
|
||||
import { asyncTryCatchIf, isOperationalError } from "./result.js";
|
||||
import { startSshTunnel } from "./ssh";
|
||||
import { ensureSshKeys, getSshKeyOpts } from "./ssh-keys";
|
||||
import { getErrorMessage } from "./type-guards";
|
||||
|
|
@ -89,6 +90,7 @@ export async function runOrchestration(
|
|||
await cloud.authenticate();
|
||||
|
||||
// 1b. Pre-flight account readiness check (billing, email verification, etc.)
|
||||
// Uses try/catch (not guarded) because hooks can throw ANY provider-specific error.
|
||||
if (cloud.checkAccountReady) {
|
||||
try {
|
||||
await cloud.checkAccountReady();
|
||||
|
|
@ -103,6 +105,7 @@ export async function runOrchestration(
|
|||
const apiKey = await getOrPromptApiKey(agentName, cloud.cloudName);
|
||||
|
||||
// 3. Pre-provision hooks (e.g., GitHub auth prompt — non-fatal)
|
||||
// Uses try/catch (not guarded) because hooks can throw ANY provider-specific error.
|
||||
if (agent.preProvision) {
|
||||
try {
|
||||
await agent.preProvision();
|
||||
|
|
@ -214,7 +217,7 @@ export async function runOrchestration(
|
|||
if (agent.tunnel) {
|
||||
if (cloud.getConnectionInfo) {
|
||||
// SSH-based cloud: tunnel the remote port to localhost
|
||||
try {
|
||||
const tunnelResult = await asyncTryCatchIf(isOperationalError, async () => {
|
||||
const conn = cloud.getConnectionInfo();
|
||||
const keys = await ensureSshKeys();
|
||||
tunnelHandle = await startSshTunnel({
|
||||
|
|
@ -229,7 +232,8 @@ export async function runOrchestration(
|
|||
openBrowser(url);
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
});
|
||||
if (!tunnelResult.ok) {
|
||||
logWarn("Web dashboard tunnel failed — use the TUI instead");
|
||||
}
|
||||
} else if (cloud.cloudName === "local") {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue