Skip to content

Commit

Permalink
Merge branch 'fix/exit-code-1-on-error' into release/cmd-1.1.1-beta
Browse files Browse the repository at this point in the history
  • Loading branch information
vCaisim committed Oct 3, 2024
2 parents 01b9eb9 + 0342c3d commit edcf15f
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 15 deletions.
110 changes: 110 additions & 0 deletions packages/cmd/src/commands/__tests__/utils.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import { CommanderError } from '@commander-js/extra-typings';
import { error, warnWithNoTrace } from '@logger';
import { describe, expect, it, vi, beforeEach } from 'vitest';
import { enableDebug } from '../../debug';
import { commandHandler, parseCommaSeparatedList } from '../utils';

vi.mock('@logger', () => ({
error: vi.fn(),
warnWithNoTrace: vi.fn(),
}));

vi.mock('../../debug', () => ({
enableDebug: vi.fn(),
}));

describe('parseCommaSeparatedList', () => {
it('should parse a single comma-separated value', () => {
const result = parseCommaSeparatedList('a,b,c');
expect(result).toEqual(['a', 'b', 'c']);
});

it('should trim values', () => {
const result = parseCommaSeparatedList(' a , b , c ');
expect(result).toEqual(['a', 'b', 'c']);
});

it('should concatenate with previous values', () => {
const result = parseCommaSeparatedList('d,e', ['a', 'b', 'c']);
expect(result).toEqual(['a', 'b', 'c', 'd', 'e']);
});

it('should return previous values if no new value is provided', () => {
const result = parseCommaSeparatedList('', ['a', 'b', 'c']);
expect(result).toEqual(['a', 'b', 'c']);
});

it('should return empty array if no value or previous is provided', () => {
const result = parseCommaSeparatedList('');
expect(result).toEqual([]);
});
});

describe('commandHandler', () => {
const mockAction = vi.fn();
let mockExit = vi.spyOn(process, 'exit').mockImplementation((code) => {
throw new Error(`process.exit(${code})`);
});

beforeEach(() => {
vi.clearAllMocks();
});

it('should call the action and exit with code 0 on success', async () => {
mockAction.mockResolvedValueOnce(undefined);
// @ts-ignore
mockExit = vi.spyOn(process, 'exit').mockImplementationOnce(() => void 0);

await commandHandler(mockAction, { debug: false });
expect(mockAction).toHaveBeenCalled();
expect(mockExit).toHaveBeenCalledWith(0);
});

it('should enable debug mode if debug is true', async () => {
mockAction.mockResolvedValueOnce(undefined);
// @ts-ignore
mockExit = vi.spyOn(process, 'exit').mockImplementationOnce(() => void 0);

await commandHandler(mockAction, { debug: true });
expect(enableDebug).toHaveBeenCalled();
expect(mockAction).toHaveBeenCalled();
expect(mockExit).toHaveBeenCalledWith(0);
});

it('should log error and exit with code 1 if an error occurs and failOnError is true', async () => {
const errorMessage = 'Test error';
mockAction.mockRejectedValueOnce(new Error(errorMessage));

await expect(commandHandler(mockAction, { debug: false })).rejects.toThrow(
'process.exit(1)'
);
expect(error).toHaveBeenCalledWith(errorMessage);
expect(mockExit).toHaveBeenCalledWith(1);
});

it('should log error and exit with specific exitCode if CommanderError occurs', async () => {
const commandError = new CommanderError(
123,
'commander.error',
'Commander failed'
);
mockAction.mockRejectedValueOnce(commandError);

await expect(commandHandler(mockAction, { debug: false })).rejects.toThrow(
'process.exit(123)'
);
expect(error).toHaveBeenCalledWith('Commander failed');
expect(mockExit).toHaveBeenCalledWith(123);
});

it('should log a warning and exit with code 0 if failOnError is false', async () => {
const errorMessage = 'Test warning';
mockAction.mockRejectedValueOnce(new Error(errorMessage));

await expect(
commandHandler(mockAction, { debug: false }, { failOnError: false })
).rejects.toThrow('process.exit(0)');
expect(warnWithNoTrace).toHaveBeenCalledWith(errorMessage);
expect(mockExit).toHaveBeenCalledWith(0);
});
});
21 changes: 6 additions & 15 deletions packages/cmd/src/commands/utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { CommanderError } from '@commander-js/extra-typings';
import { ValidationError } from '@lib';
import { error, warnWithNoTrace } from '@logger';
import { isAxiosError } from 'axios';
import { enableDebug } from '../debug';

export function parseCommaSeparatedList(
Expand All @@ -27,21 +25,14 @@ export async function commandHandler<T extends Record<string, unknown>>(
}
await action(commandOptions);
process.exit(0);
} catch (e) {
} catch (_e) {
console.log(_e);
const e = _e as Error;
const failOnError = options?.failOnError ?? true;

if (
e instanceof CommanderError ||
e instanceof ValidationError ||
isAxiosError(e)
) {
if (failOnError) {
error(e.message);
} else {
warnWithNoTrace(e.message);
}
if (failOnError) {
error(e.message);
} else {
error('Script execution failed: %o', e);
warnWithNoTrace(e.message);
}

const exitCode = e instanceof CommanderError ? e.exitCode : 1;
Expand Down

0 comments on commit edcf15f

Please sign in to comment.