chore: Move the duplicated CLI command error banner into BaseCommand (#38298)

Co-authored-by: n8n-cat-bot[bot] <n8n-cat-bot[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
n8n-cat-bot[bot] 2026-09-10 10:27:32 +00:00 committed by GitHub
parent 75e44b65cb
commit 481c494df0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 58 additions and 23 deletions

View File

@ -0,0 +1,44 @@
import { Logger } from '@n8n/backend-common';
import { mockInstance } from '@n8n/backend-test-utils';
import { BaseCommand } from '../base-command';
class TestCommand extends BaseCommand {
async run() {}
}
const logger = mockInstance(Logger);
afterEach(() => {
vi.resetAllMocks();
});
describe('logError', () => {
const error = new Error('Something went wrong');
error.stack = 'the stack';
it('should log the error banner', () => {
// @ts-expect-error Protected method
new TestCommand().logError(error);
expect(logger.error.mock.calls.flat()).toEqual([
'\nGOT ERROR',
'====================================',
'Something went wrong',
'the stack',
]);
});
it('should log the summary before the error banner', () => {
// @ts-expect-error Protected method
new TestCommand().logError(error, 'Error updating database.');
expect(logger.error.mock.calls.flat()).toEqual([
'Error updating database.',
'\nGOT ERROR',
'====================================',
'Something went wrong',
'the stack',
]);
});
});

View File

@ -331,6 +331,15 @@ export abstract class BaseCommand<F = never> {
throw new UnexpectedError(message);
}
/** Print an error banner, optionally preceded by a command-specific summary. */
protected logError(error: Error, summary?: string) {
if (summary) this.logger.error(summary);
this.logger.error('\nGOT ERROR');
this.logger.error('====================================');
this.logger.error(error.message);
this.logger.error(error.stack!);
}
async initBinaryDataService() {
const binaryDataConfig = Container.get(BinaryDataConfig);
const binaryDataService = Container.get(BinaryDataService);

View File

@ -42,9 +42,6 @@ export class ListWorkflowCommand extends BaseCommand<z.infer<typeof flagsSchema>
}
async catch(error: Error) {
this.logger.error('\nGOT ERROR');
this.logger.error('====================================');
this.logger.error(error.message);
this.logger.error(error.stack!);
this.logError(error);
}
}

View File

@ -47,10 +47,6 @@ export class PublishWorkflowCommand extends BaseCommand<z.infer<typeof flagsSche
}
async catch(error: Error) {
this.logger.error('Error updating database. See log messages for details.');
this.logger.error('\nGOT ERROR');
this.logger.error('====================================');
this.logger.error(error.message);
this.logger.error(error.stack!);
this.logError(error, 'Error updating database. See log messages for details.');
}
}

View File

@ -209,9 +209,6 @@ export class TTWFGenerateCommand extends BaseCommand<z.infer<typeof flagsSchema>
}
async catch(error: Error) {
this.logger.error('\nGOT ERROR');
this.logger.error('====================================');
this.logger.error(error.message);
this.logger.error(error.stack!);
this.logError(error);
}
}

View File

@ -45,10 +45,6 @@ export class UnpublishWorkflowCommand extends BaseCommand<z.infer<typeof flagsSc
}
async catch(error: Error) {
this.logger.error('Error unpublishing workflow(s). See log messages for details.');
this.logger.error('\nGOT ERROR');
this.logger.error('====================================');
this.logger.error(error.message);
this.logger.error(error.stack!);
this.logError(error, 'Error unpublishing workflow(s). See log messages for details.');
}
}

View File

@ -96,10 +96,6 @@ export class UpdateWorkflowCommand extends BaseCommand<z.infer<typeof flagsSchem
}
async catch(error: Error) {
this.logger.error('Error updating database. See log messages for details.');
this.logger.error('\nGOT ERROR');
this.logger.error('====================================');
this.logger.error(error.message);
this.logger.error(error.stack!);
this.logError(error, 'Error updating database. See log messages for details.');
}
}