-
Notifications
You must be signed in to change notification settings - Fork 449
fix: improve ax error handling around missing commands or unknown flags #8116
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
987b2db
3f12a30
e7d95dd
f5f623c
c5cfbbb
7d47f84
b5d55c4
e6e3b93
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| import { CommanderError, type HelpContext } from 'commander' | ||
|
|
||
| import { log } from './command-helpers.js' | ||
| import { isInteractive } from './scripted-commands.js' | ||
|
|
||
| const OPTION_ERROR_CODES = new Set([ | ||
| 'commander.unknownOption', | ||
| 'commander.missingArgument', | ||
| 'commander.excessArguments', | ||
| ]) | ||
|
|
||
| export const isOptionError = (error: CommanderError): boolean => OPTION_ERROR_CODES.has(error.code) | ||
|
|
||
| export const handleOptionError = (command: { outputHelp: (context?: HelpContext) => void }): void => { | ||
| if (!isInteractive()) { | ||
| log() | ||
| command.outputHelp({ error: true }) | ||
| log() | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| import { describe, test } from 'vitest' | ||
|
|
||
| import { callCli } from '../../utils/call-cli.js' | ||
| import { normalize } from '../../utils/snapshots.js' | ||
|
|
||
| describe('error handling', () => { | ||
| test('unknown option shows error message', async (t) => { | ||
| try { | ||
| await callCli(['status', '--invalid-option']) | ||
| t.expect.fail('Expected callCli to throw') | ||
| } catch (error) { | ||
| const stderr = (error as { stderr: string }).stderr | ||
| const normalized = normalize(stderr) | ||
|
|
||
| // In interactive mode (test environment), shows brief error | ||
| t.expect(normalized).toContain('Error: unknown option') | ||
| t.expect(normalized).toContain('See more help with --help') | ||
| } | ||
|
Comment on lines
+7
to
+18
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Assert the new help-on-error contract from the same failed run. These cases only check the generic error banner and then rerun the CLI, so a regression where the extra help text disappears or lands on the wrong stream would still pass. Capture the rejected Also applies to: 22-48 π€ Prompt for AI Agents |
||
| }) | ||
|
|
||
| test('unknown command shows error', async (t) => { | ||
| try { | ||
| await callCli(['statuss']) | ||
| t.expect.fail('Expected callCli to throw') | ||
| } catch (error) { | ||
| const stderr = (error as { stderr: string }).stderr | ||
| const normalized = normalize(stderr) | ||
|
|
||
| // Shows error with help suggestion | ||
| t.expect(normalized).toContain('Error') | ||
| t.expect(normalized).toContain('netlify help') | ||
| } | ||
| }) | ||
|
|
||
| test('missing required argument shows error', async (t) => { | ||
| try { | ||
| await callCli(['sites:delete']) | ||
| t.expect.fail('Expected callCli to throw') | ||
| } catch (error) { | ||
| const stderr = (error as { stderr: string }).stderr | ||
| const normalized = normalize(stderr) | ||
|
|
||
| t.expect(normalized).toContain('Error:') | ||
| t.expect(normalized).toContain('missing required argument') | ||
| } | ||
| }) | ||
|
|
||
| test('help command works correctly', async (t) => { | ||
| const helpOutput = (await callCli(['status', '--help'])) as string | ||
| const normalized = normalize(helpOutput) | ||
|
|
||
| t.expect(normalized).toContain('Print status information') | ||
| t.expect(normalized).toContain('USAGE') | ||
| t.expect(normalized).toContain('OPTIONS') | ||
| }) | ||
| }) | ||
Uh oh!
There was an error while loading. Please reload this page.