Skip to content

Commit a1766c2

Browse files
committed
refactor: gate stderr message override to process-exit errors
1 parent 61a5446 commit a1766c2

3 files changed

Lines changed: 43 additions & 4 deletions

File tree

src/utils/__tests__/errors.test.ts

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,41 @@ test('normalizeError falls back to context metadata', () => {
3434

3535
test('normalizeError enriches generic command-failed message with stderr excerpt', () => {
3636
const err = new AppError('COMMAND_FAILED', 'xcrun exited with code 1', {
37+
exitCode: 1,
38+
processExitError: true,
3739
stderr: '\nOperation not permitted\nUnderlying error details',
3840
});
3941
const normalized = normalizeError(err);
40-
assert.equal(normalized.message, 'xcrun exited with code 1: Operation not permitted');
42+
assert.equal(normalized.message, 'Operation not permitted');
4143
});
4244

43-
test('normalizeError does not alter non-generic command-failed message', () => {
45+
test('normalizeError skips simctl boilerplate wrappers in stderr', () => {
46+
const err = new AppError('COMMAND_FAILED', 'xcrun exited with code 1', {
47+
exitCode: 1,
48+
processExitError: true,
49+
stderr: [
50+
'An error was encountered processing the command (domain=NSPOSIXErrorDomain, code=1):',
51+
'Simulator device failed to complete the requested operation.',
52+
'Operation not permitted',
53+
'Underlying error (domain=NSPOSIXErrorDomain, code=1):',
54+
'\tFailed to reset access',
55+
'\tOperation not permitted',
56+
].join('\n'),
57+
});
58+
const normalized = normalizeError(err);
59+
assert.equal(normalized.message, 'Operation not permitted');
60+
});
61+
62+
test('normalizeError does not alter generic command-failed message without process-exit marker', () => {
63+
const err = new AppError('COMMAND_FAILED', 'xcrun exited with code 1', {
64+
exitCode: 1,
65+
stderr: 'Operation not permitted',
66+
});
67+
const normalized = normalizeError(err);
68+
assert.equal(normalized.message, 'xcrun exited with code 1');
69+
});
70+
71+
test('normalizeError does not alter non-generic command-failed message without exitCode details', () => {
4472
const err = new AppError('COMMAND_FAILED', 'Failed to reset access', {
4573
stderr: 'Operation not permitted',
4674
});

src/utils/errors.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,17 +86,24 @@ function maybeEnrichCommandFailedMessage(
8686
details: Record<string, unknown> | undefined,
8787
): string {
8888
if (code !== 'COMMAND_FAILED') return message;
89-
if (!/\bexited with code\b/i.test(message)) return message;
89+
if (details?.processExitError !== true) return message;
9090
const stderr = typeof details?.stderr === 'string' ? details.stderr : '';
9191
const excerpt = firstStderrLine(stderr);
9292
if (!excerpt) return message;
93-
return `${message}: ${excerpt}`;
93+
return excerpt;
9494
}
9595

9696
function firstStderrLine(stderr: string): string | null {
97+
const skipPatterns = [
98+
/^an error was encountered processing the command/i,
99+
/^underlying error\b/i,
100+
/^simulator device failed to complete the requested operation/i,
101+
];
102+
97103
for (const rawLine of stderr.split('\n')) {
98104
const line = rawLine.trim();
99105
if (!line) continue;
106+
if (skipPatterns.some((pattern) => pattern.test(line))) continue;
100107
return line.length > 200 ? `${line.slice(0, 200)}...` : line;
101108
}
102109
return null;

src/utils/exec.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ export async function runCmd(
111111
stdout,
112112
stderr,
113113
exitCode,
114+
processExitError: true,
114115
}),
115116
);
116117
return;
@@ -176,6 +177,7 @@ export function runCmdSync(cmd: string, args: string[], options: ExecOptions = {
176177
stdout,
177178
stderr,
178179
exitCode,
180+
processExitError: true,
179181
});
180182
}
181183

@@ -256,6 +258,7 @@ export async function runCmdStreaming(
256258
stdout,
257259
stderr,
258260
exitCode,
261+
processExitError: true,
259262
}),
260263
);
261264
return;
@@ -309,6 +312,7 @@ export function runCmdBackground(
309312
stdout,
310313
stderr,
311314
exitCode,
315+
processExitError: true,
312316
}),
313317
);
314318
return;

0 commit comments

Comments
 (0)