Skip to content

Commit ad49d55

Browse files
chore: move to SfCommandError, find multiple errors correctly
1 parent d9f7a6d commit ad49d55

File tree

3 files changed

+39
-18
lines changed

3 files changed

+39
-18
lines changed

src/SfCommandError.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,40 @@ export class SfCommandError extends SfError {
9595
result: this.result,
9696
};
9797
}
98+
99+
public appendErrorSuggestions(): void {
100+
const output =
101+
// @ts-expect-error error's causes aren't typed, this is what's returned from flag parsing errors
102+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
103+
(this.cause?.parse?.output?.raw as Array<{ flag: string; input: string; type: 'flag' | 'arg' }>) ?? [];
104+
105+
/*
106+
if there's a group of args, and additional args separated, we could have multiple suggestions
107+
--first my first --second my second =>
108+
try this:
109+
--first "my first"
110+
--second "my second"
111+
*/
112+
113+
// find the flag before the 'args' block that's valid, to append the args with its value as a suggestion
114+
// const target = output.find((flag, index) => flag.type === 'flag' && output[index + 1]?.type === 'arg');
115+
116+
const catcher: Array<{ flag: string; args: string[] }> = [];
117+
output.forEach((k, i) => {
118+
let argCounter = i + 1;
119+
if (k.type === 'flag' && output[argCounter].type === 'arg') {
120+
const args: string[] = [];
121+
// add the flag name, and first correctly parsed value to the suggestion
122+
123+
while (output[argCounter]?.type === 'arg') {
124+
args.push(output[argCounter].input);
125+
argCounter++;
126+
}
127+
catcher.push({ flag: k.flag, args: [k.input, ...args] });
128+
}
129+
});
130+
131+
this.actions ??= [];
132+
this.actions.push(...catcher.map((cause) => `--${cause.flag} "${cause.args.join(' ')}"`));
133+
}
98134
}

src/sfCommand.ts

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -382,22 +382,7 @@ export abstract class SfCommand<T> extends Command {
382382
sfCommandError.exitCode === 2 &&
383383
error.message.includes('Unexpected argument')
384384
) {
385-
const output =
386-
// @ts-expect-error error's causes aren't typed, this is what's returned from flag parsing errors
387-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
388-
(sfCommandError.cause?.parse?.output?.raw as Array<{ flag: string; input: string; type: 'flag' | 'arg' }>) ??
389-
[];
390-
391-
// find the extra arguments causing issues
392-
const extras = output
393-
.filter((f) => f.type === 'arg')
394-
.flatMap((f) => f.input)
395-
.join(' ');
396-
// find the flag before the 'args' block that's valid, to append the args with its value as a suggestion
397-
const target = output.find((flag, index) => flag.type === 'flag' && output[index + 1]?.type === 'arg');
398-
399-
sfCommandError.actions ??= [];
400-
sfCommandError.actions.push(`--${target?.flag} "${target?.input} ${extras}"`);
385+
sfCommandError.appendErrorSuggestions();
401386
}
402387

403388
if (this.jsonEnabled()) {

test/unit/sfCommand.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ describe('error standardization', () => {
395395
it('should log correct suggestion when user doesnt wrap with quotes', async () => {
396396
const logToStderrStub = $$.SANDBOX.stub(SfCommand.prototype, 'logToStderr');
397397
try {
398-
await SuggestionCommand.run(['--first', 'my', 'alias', 'with', 'spaces', '--second', 'my second value']);
398+
await SuggestionCommand.run(['--first', 'my', 'alias', 'with', 'spaces', '--second', 'my second', 'value']);
399399
expect(false, 'error should have been thrown').to.be.true;
400400
} catch (e: unknown) {
401401
expect(e).to.be.instanceOf(SfCommandError);
@@ -407,7 +407,7 @@ describe('error standardization', () => {
407407

408408
// Ensure the error has expected properties
409409
expect(err).to.have.property('actions');
410-
expect(err.actions).to.deep.equal(['--first "my alias with spaces"']);
410+
expect(err.actions).to.deep.equal(['--first "my alias with spaces"', '--second "my second value"']);
411411
expect(err).to.have.property('exitCode', 2);
412412
expect(err).to.have.property('context', 'SuggestionCommand');
413413
expect(err).to.have.property('data', undefined);

0 commit comments

Comments
 (0)