fix: Improve error handling and state management in auto-mode and utilities

This commit is contained in:
gsxdsm
2026-02-18 23:12:11 -08:00
parent a144a63c51
commit be4153c374
4 changed files with 32 additions and 22 deletions

View File

@@ -845,11 +845,9 @@ export class CodexProvider extends BaseProvider {
options.model,
CODEX_JSON_FLAG,
...configOverrideArgs,
...(schemaPath ? [CODEX_OUTPUT_SCHEMA_FLAG, schemaPath] : []),
'-', // Read prompt from stdin to avoid shell escaping issues
];
if (schemaPath) {
args.push(CODEX_OUTPUT_SCHEMA_FLAG, schemaPath);
}
const envOverrides = buildEnv();
if (executionPlan.openAiApiKey && !envOverrides[OPENAI_API_KEY_ENV]) {

View File

@@ -519,15 +519,22 @@ export class AutoModeServiceFacade {
useWorktrees = false,
_calledInternally = false
): Promise<void> {
// Do not call handleFacadeError here: ExecutionService.executeFeature already
// classifies and emits auto_mode_error, so calling handleFacadeError would
// produce duplicate error events. Simply let the error propagate to the caller.
return await this.recoveryService.resumeFeature(
this.projectPath,
featureId,
useWorktrees,
_calledInternally
);
// Note: ExecutionService.executeFeature catches its own errors internally and
// does NOT re-throw them (it emits auto_mode_error and returns normally).
// Therefore, errors that reach this catch block are pre-execution failures
// (e.g., feature not found, context read error) that ExecutionService never
// handled — so calling handleFacadeError here does NOT produce duplicate events.
try {
return await this.recoveryService.resumeFeature(
this.projectPath,
featureId,
useWorktrees,
_calledInternally
);
} catch (error) {
this.handleFacadeError(error, 'resumeFeature', featureId);
throw error;
}
}
/**

View File

@@ -92,20 +92,22 @@ export async function stashChanges(
}
args.push('-m', message);
await execGitCommandWithLockRetry(args, cwd);
const stdout = await execGitCommandWithLockRetry(args, cwd);
// git exits 0 but prints a benign message when there is nothing to stash
const stdoutLower = stdout.toLowerCase();
if (
stdoutLower.includes('no local changes to save') ||
stdoutLower.includes('nothing to stash')
) {
logger.debug('stashChanges: nothing to stash', { cwd, message, stdout });
return false;
}
return true;
} catch (error) {
const errorMsg = getErrorMessage(error);
// "Nothing to stash" is benign no work was lost, just return false
if (
errorMsg.toLowerCase().includes('no local changes to save') ||
errorMsg.toLowerCase().includes('nothing to stash')
) {
logger.debug('stashChanges: nothing to stash', { cwd, message, error: errorMsg });
return false;
}
// Unexpected error log full details and re-throw so the caller aborts
// rather than proceeding with an un-stashed working tree
logger.error('stashChanges: unexpected error during stash', {

View File

@@ -112,6 +112,9 @@ export function CreateBranchDialog({
if (open) {
setBranchName('');
setBaseBranch('');
// Update the ref synchronously so fetchBranches() sees the cleared value
// immediately, rather than the stale value from the previous open.
baseBranchRef.current = '';
setError(null);
setBranches([]);
setBaseBranchPopoverOpen(false);