From 443a648a9860fcc1f10d8661cecc464fb77d8c52 Mon Sep 17 00:00:00 2001 From: Julius Marminge Date: Sat, 20 Jun 2026 05:16:31 -0700 Subject: [PATCH 1/2] [codex] Split preferred editor precondition errors Co-authored-by: codex --- apps/web/src/editorPreferences.ts | 45 +++++++++++++++++-------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/apps/web/src/editorPreferences.ts b/apps/web/src/editorPreferences.ts index 32bdf42a807..63ba4bb5272 100644 --- a/apps/web/src/editorPreferences.ts +++ b/apps/web/src/editorPreferences.ts @@ -5,7 +5,7 @@ import { type AtomCommandResult, } from "@t3tools/client-runtime/state/runtime"; import * as Cause from "effect/Cause"; -import * as Data from "effect/Data"; +import * as Schema from "effect/Schema"; import { AsyncResult } from "effect/unstable/reactivity"; import { getLocalStorageItem, setLocalStorageItem, useLocalStorage } from "./hooks/useLocalStorage"; import { useCallback, useMemo } from "react"; @@ -14,11 +14,23 @@ import { useAtomCommand } from "./state/use-atom-command"; const LAST_EDITOR_KEY = "t3code:last-editor"; -export class PreferredEditorUnavailableError extends Data.TaggedError( +export class OpenInEditorEnvironmentNotSelectedError extends Schema.TaggedErrorClass()( + "OpenInEditorEnvironmentNotSelectedError", + {}, +) { + override get message(): string { + return "No environment is selected."; + } +} + +export class PreferredEditorUnavailableError extends Schema.TaggedErrorClass()( "PreferredEditorUnavailableError", -)<{ - readonly message: string; -}> {} + {}, +) { + override get message(): string { + return "No available editors found."; + } +} export function usePreferredEditor(availableEditors: ReadonlyArray) { const [lastEditor, setLastEditor] = useLocalStorage(LAST_EDITOR_KEY, null, EditorId); @@ -55,26 +67,19 @@ export function useOpenInPreferredEditor( async ( targetPath: string, ): Promise< - AtomCommandResult + AtomCommandResult< + EditorId, + | OpenInEditorError + | OpenInEditorEnvironmentNotSelectedError + | PreferredEditorUnavailableError + > > => { if (environmentId === null) { - return AsyncResult.failure( - Cause.fail( - new PreferredEditorUnavailableError({ - message: "No environment is selected.", - }), - ), - ); + return AsyncResult.failure(Cause.fail(new OpenInEditorEnvironmentNotSelectedError())); } const editor = resolveAndPersistPreferredEditor(availableEditors); if (!editor) { - return AsyncResult.failure( - Cause.fail( - new PreferredEditorUnavailableError({ - message: "No available editors found.", - }), - ), - ); + return AsyncResult.failure(Cause.fail(new PreferredEditorUnavailableError())); } const result = await openInEditor({ environmentId, From 9f64e276c12930a58b61ef11549809386285944c Mon Sep 17 00:00:00 2001 From: Julius Marminge Date: Sat, 20 Jun 2026 07:51:24 -0700 Subject: [PATCH 2/2] Enrich preferred editor failures Co-authored-by: codex --- apps/web/src/editorPreferences.ts | 40 +++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/apps/web/src/editorPreferences.ts b/apps/web/src/editorPreferences.ts index 63ba4bb5272..d691ddb3153 100644 --- a/apps/web/src/editorPreferences.ts +++ b/apps/web/src/editorPreferences.ts @@ -1,4 +1,4 @@ -import { EDITORS, EditorId, type EnvironmentId } from "@t3tools/contracts"; +import { EDITORS, EditorId, EnvironmentId } from "@t3tools/contracts"; import { mapAtomCommandResult, type AtomCommandFailure, @@ -14,21 +14,27 @@ import { useAtomCommand } from "./state/use-atom-command"; const LAST_EDITOR_KEY = "t3code:last-editor"; -export class OpenInEditorEnvironmentNotSelectedError extends Schema.TaggedErrorClass()( - "OpenInEditorEnvironmentNotSelectedError", - {}, +export class PreferredEditorEnvironmentRequiredError extends Schema.TaggedErrorClass()( + "PreferredEditorEnvironmentRequiredError", + { + targetPath: Schema.String, + }, ) { override get message(): string { - return "No environment is selected."; + return `Cannot open ${this.targetPath} because no environment is selected.`; } } export class PreferredEditorUnavailableError extends Schema.TaggedErrorClass()( "PreferredEditorUnavailableError", - {}, + { + environmentId: EnvironmentId, + targetPath: Schema.String, + availableEditorIds: Schema.Array(EditorId), + }, ) { override get message(): string { - return "No available editors found."; + return `No available editor can open ${this.targetPath} in environment ${this.environmentId}.`; } } @@ -70,16 +76,30 @@ export function useOpenInPreferredEditor( AtomCommandResult< EditorId, | OpenInEditorError - | OpenInEditorEnvironmentNotSelectedError + | PreferredEditorEnvironmentRequiredError | PreferredEditorUnavailableError > > => { if (environmentId === null) { - return AsyncResult.failure(Cause.fail(new OpenInEditorEnvironmentNotSelectedError())); + return AsyncResult.failure( + Cause.fail( + new PreferredEditorEnvironmentRequiredError({ + targetPath, + }), + ), + ); } const editor = resolveAndPersistPreferredEditor(availableEditors); if (!editor) { - return AsyncResult.failure(Cause.fail(new PreferredEditorUnavailableError())); + return AsyncResult.failure( + Cause.fail( + new PreferredEditorUnavailableError({ + environmentId, + targetPath, + availableEditorIds: availableEditors, + }), + ), + ); } const result = await openInEditor({ environmentId,