Skip to content

Commit a1f095e

Browse files
committed
🐛 Fix error path cleanup consistency and add field selection warning
Address PR review feedback: - Add output.cleanup() to all error paths before process.exit() - Add debug-level warning when field selection doesn't find requested fields - Ensures spinners and other terminal state are properly cleaned up on errors Files fixed: - api.js, review.js (approve/reject/comment), builds.js, comparisons.js - config-cmd.js, orgs.js, projects.js, baselines.js
1 parent eb79e55 commit a1f095e

File tree

9 files changed

+28
-0
lines changed

9 files changed

+28
-0
lines changed

src/commands/api.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ export async function apiCommand(
176176
}
177177

178178
output.error('API request failed', error);
179+
output.cleanup();
179180
exit(1);
180181
}
181182
}

src/commands/baselines.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ export async function baselinesCommand(
127127
return;
128128
}
129129
output.error(`Baseline "${options.info}" not found`);
130+
output.cleanup();
130131
exit(1);
131132
return;
132133
}
@@ -287,6 +288,7 @@ export async function baselinesCommand(
287288
output.cleanup();
288289
} catch (error) {
289290
output.error('Failed to read baselines', error);
291+
output.cleanup();
290292
exit(1);
291293
}
292294
}

src/commands/builds.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ export async function buildsCommand(
161161
} catch (error) {
162162
output.stopSpinner();
163163
output.error('Failed to fetch builds', error);
164+
output.cleanup();
164165
exit(1);
165166
}
166167
}

src/commands/comparisons.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ export async function comparisonsCommand(
178178
} catch (error) {
179179
output.stopSpinner();
180180
output.error('Failed to fetch comparisons', error);
181+
output.cleanup();
181182
exit(1);
182183
}
183184
}

src/commands/config-cmd.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ export async function configCommand(
146146
output.cleanup();
147147
} catch (error) {
148148
output.error('Failed to load configuration', error);
149+
output.cleanup();
149150
exit(1);
150151
}
151152
}

src/commands/orgs.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export async function orgsCommand(_options = {}, globalOptions = {}) {
2626
output.error(
2727
'API token required. Use --token, set VIZZLY_TOKEN, or run "vizzly login"'
2828
);
29+
output.cleanup();
2930
process.exit(1);
3031
}
3132

@@ -81,6 +82,7 @@ export async function orgsCommand(_options = {}, globalOptions = {}) {
8182
} catch (error) {
8283
output.stopSpinner();
8384
output.error('Failed to fetch organizations', error);
85+
output.cleanup();
8486
process.exit(1);
8587
}
8688
}

src/commands/projects.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export async function projectsCommand(options = {}, globalOptions = {}) {
2626
output.error(
2727
'API token required. Use --token, set VIZZLY_TOKEN, or run "vizzly login"'
2828
);
29+
output.cleanup();
2930
process.exit(1);
3031
}
3132

@@ -103,6 +104,7 @@ export async function projectsCommand(options = {}, globalOptions = {}) {
103104
} catch (error) {
104105
output.stopSpinner();
105106
output.error('Failed to fetch projects', error);
107+
output.cleanup();
106108
process.exit(1);
107109
}
108110
}

src/commands/review.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ export async function approveCommand(
101101
}
102102

103103
output.error('Failed to approve comparison', error);
104+
output.cleanup();
104105
exit(1);
105106
}
106107
}
@@ -198,6 +199,7 @@ export async function rejectCommand(
198199
}
199200

200201
output.error('Failed to reject comparison', error);
202+
output.cleanup();
201203
exit(1);
202204
}
203205
}
@@ -298,6 +300,7 @@ export async function commentCommand(
298300
}
299301

300302
output.error('Failed to add comment', error);
303+
output.cleanup();
301304
exit(1);
302305
}
303306
}

src/utils/output.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ function setNestedValue(obj, path, value) {
129129
/**
130130
* Select specific fields from an object
131131
* Supports dot notation for nested fields (e.g., "comparisons.total")
132+
* Warns in debug mode when requested fields aren't found
132133
* @param {Object|Array} obj - Source object or array
133134
* @param {string[]} fields - Fields to select
134135
* @returns {Object|Array} Object with only selected fields
@@ -143,12 +144,26 @@ function selectFields(obj, fields) {
143144
}
144145

145146
let result = {};
147+
let missingFields = [];
148+
146149
for (let field of fields) {
147150
let value = getNestedValue(obj, field);
148151
if (value !== undefined) {
149152
setNestedValue(result, field, value);
153+
} else {
154+
missingFields.push(field);
150155
}
151156
}
157+
158+
// Warn about missing fields in verbose mode
159+
if (missingFields.length > 0 && shouldLog('debug')) {
160+
console.error(
161+
colors.dim(
162+
`Note: Requested field(s) not found: ${missingFields.join(', ')}`
163+
)
164+
);
165+
}
166+
152167
return result;
153168
}
154169

0 commit comments

Comments
 (0)