mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-04-30 12:40:44 +00:00
refactor(debug): replace ConsolePatcher with debugLogger and update error reporting
- Replace ConsolePatcher with centralized debugLogger utility - Refactor errorReporting to use debugLogger instead of file-based reporting - Remove user-facing console message components: - Delete ConsolePatcher.ts, useConsoleMessages.ts/hook - Delete ConsoleSummaryDisplay.tsx, DetailedMessagesDisplay.tsx - Update all tests in packages/core and packages/cli: - Mock debugLogger where needed - Remove assertions for console output on non-critical errors - Keep debugLogger assertions for fatal/network errors - Use HOME directory mocking for hermetic file system tests Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
parent
135df54f27
commit
89e3c2cd7a
64 changed files with 1240 additions and 2416 deletions
|
|
@ -20,6 +20,15 @@ import type { Settings } from './settings.js';
|
|||
import * as ServerConfig from '@qwen-code/qwen-code-core';
|
||||
import { isWorkspaceTrusted } from './trustedFolders.js';
|
||||
|
||||
const mockWriteStderrLine = vi.hoisted(() => vi.fn());
|
||||
const mockWriteStdoutLine = vi.hoisted(() => vi.fn());
|
||||
|
||||
vi.mock('../utils/stdioHelpers.js', () => ({
|
||||
writeStderrLine: mockWriteStderrLine,
|
||||
writeStdoutLine: mockWriteStdoutLine,
|
||||
clearScreen: vi.fn(),
|
||||
}));
|
||||
|
||||
const createNativeLspServiceInstance = () => ({
|
||||
discoverAndPrepare: vi.fn(),
|
||||
start: vi.fn(),
|
||||
|
|
@ -158,23 +167,19 @@ describe('parseArguments', () => {
|
|||
const mockExit = vi.spyOn(process, 'exit').mockImplementation(() => {
|
||||
throw new Error('process.exit called');
|
||||
});
|
||||
|
||||
const mockConsoleError = vi
|
||||
.spyOn(console, 'error')
|
||||
.mockImplementation(() => {});
|
||||
mockWriteStderrLine.mockClear();
|
||||
|
||||
await expect(parseArguments({} as Settings)).rejects.toThrow(
|
||||
'process.exit called',
|
||||
);
|
||||
|
||||
expect(mockConsoleError).toHaveBeenCalledWith(
|
||||
expect(mockWriteStderrLine).toHaveBeenCalledWith(
|
||||
expect.stringContaining(
|
||||
'Cannot use both --prompt (-p) and --prompt-interactive (-i) together',
|
||||
),
|
||||
);
|
||||
|
||||
mockExit.mockRestore();
|
||||
mockConsoleError.mockRestore();
|
||||
});
|
||||
|
||||
it('should throw an error when using short flags -p and -i together', async () => {
|
||||
|
|
@ -190,23 +195,19 @@ describe('parseArguments', () => {
|
|||
const mockExit = vi.spyOn(process, 'exit').mockImplementation(() => {
|
||||
throw new Error('process.exit called');
|
||||
});
|
||||
|
||||
const mockConsoleError = vi
|
||||
.spyOn(console, 'error')
|
||||
.mockImplementation(() => {});
|
||||
mockWriteStderrLine.mockClear();
|
||||
|
||||
await expect(parseArguments({} as Settings)).rejects.toThrow(
|
||||
'process.exit called',
|
||||
);
|
||||
|
||||
expect(mockConsoleError).toHaveBeenCalledWith(
|
||||
expect(mockWriteStderrLine).toHaveBeenCalledWith(
|
||||
expect.stringContaining(
|
||||
'Cannot use both --prompt (-p) and --prompt-interactive (-i) together',
|
||||
),
|
||||
);
|
||||
|
||||
mockExit.mockRestore();
|
||||
mockConsoleError.mockRestore();
|
||||
});
|
||||
|
||||
it('should allow --prompt without --prompt-interactive', async () => {
|
||||
|
|
@ -389,23 +390,19 @@ describe('parseArguments', () => {
|
|||
const mockExit = vi.spyOn(process, 'exit').mockImplementation(() => {
|
||||
throw new Error('process.exit called');
|
||||
});
|
||||
|
||||
const mockConsoleError = vi
|
||||
.spyOn(console, 'error')
|
||||
.mockImplementation(() => {});
|
||||
mockWriteStderrLine.mockClear();
|
||||
|
||||
await expect(parseArguments({} as Settings)).rejects.toThrow(
|
||||
'process.exit called',
|
||||
);
|
||||
|
||||
expect(mockConsoleError).toHaveBeenCalledWith(
|
||||
expect(mockWriteStderrLine).toHaveBeenCalledWith(
|
||||
expect.stringContaining(
|
||||
'Cannot use both --yolo (-y) and --approval-mode together. Use --approval-mode=yolo instead.',
|
||||
),
|
||||
);
|
||||
|
||||
mockExit.mockRestore();
|
||||
mockConsoleError.mockRestore();
|
||||
});
|
||||
|
||||
it('should throw an error when using short flags -y and --approval-mode together', async () => {
|
||||
|
|
@ -414,23 +411,19 @@ describe('parseArguments', () => {
|
|||
const mockExit = vi.spyOn(process, 'exit').mockImplementation(() => {
|
||||
throw new Error('process.exit called');
|
||||
});
|
||||
|
||||
const mockConsoleError = vi
|
||||
.spyOn(console, 'error')
|
||||
.mockImplementation(() => {});
|
||||
mockWriteStderrLine.mockClear();
|
||||
|
||||
await expect(parseArguments({} as Settings)).rejects.toThrow(
|
||||
'process.exit called',
|
||||
);
|
||||
|
||||
expect(mockConsoleError).toHaveBeenCalledWith(
|
||||
expect(mockWriteStderrLine).toHaveBeenCalledWith(
|
||||
expect.stringContaining(
|
||||
'Cannot use both --yolo (-y) and --approval-mode together. Use --approval-mode=yolo instead.',
|
||||
),
|
||||
);
|
||||
|
||||
mockExit.mockRestore();
|
||||
mockConsoleError.mockRestore();
|
||||
});
|
||||
|
||||
it('should throw an error when include-partial-messages is used without stream-json output', async () => {
|
||||
|
|
@ -439,23 +432,19 @@ describe('parseArguments', () => {
|
|||
const mockExit = vi.spyOn(process, 'exit').mockImplementation(() => {
|
||||
throw new Error('process.exit called');
|
||||
});
|
||||
|
||||
const mockConsoleError = vi
|
||||
.spyOn(console, 'error')
|
||||
.mockImplementation(() => {});
|
||||
mockWriteStderrLine.mockClear();
|
||||
|
||||
await expect(parseArguments({} as Settings)).rejects.toThrow(
|
||||
'process.exit called',
|
||||
);
|
||||
|
||||
expect(mockConsoleError).toHaveBeenCalledWith(
|
||||
expect(mockWriteStderrLine).toHaveBeenCalledWith(
|
||||
expect.stringContaining(
|
||||
'--include-partial-messages requires --output-format stream-json',
|
||||
),
|
||||
);
|
||||
|
||||
mockExit.mockRestore();
|
||||
mockConsoleError.mockRestore();
|
||||
});
|
||||
|
||||
it('should parse stream-json formats and include-partial-messages flag', async () => {
|
||||
|
|
@ -496,21 +485,17 @@ describe('parseArguments', () => {
|
|||
const mockExit = vi.spyOn(process, 'exit').mockImplementation(() => {
|
||||
throw new Error('process.exit called');
|
||||
});
|
||||
|
||||
const mockConsoleError = vi
|
||||
.spyOn(console, 'error')
|
||||
.mockImplementation(() => {});
|
||||
mockWriteStderrLine.mockClear();
|
||||
|
||||
await expect(parseArguments({} as Settings)).rejects.toThrow(
|
||||
'process.exit called',
|
||||
);
|
||||
|
||||
expect(mockConsoleError).toHaveBeenCalledWith(
|
||||
expect(mockWriteStderrLine).toHaveBeenCalledWith(
|
||||
expect.stringContaining('Invalid values:'),
|
||||
);
|
||||
|
||||
mockExit.mockRestore();
|
||||
mockConsoleError.mockRestore();
|
||||
});
|
||||
|
||||
it('should support comma-separated values for --allowed-tools', async () => {
|
||||
|
|
@ -900,21 +885,17 @@ describe('loadCliConfig telemetry', () => {
|
|||
const mockExit = vi.spyOn(process, 'exit').mockImplementation(() => {
|
||||
throw new Error('process.exit called');
|
||||
});
|
||||
|
||||
const mockConsoleError = vi
|
||||
.spyOn(console, 'error')
|
||||
.mockImplementation(() => {});
|
||||
mockWriteStderrLine.mockClear();
|
||||
|
||||
await expect(parseArguments({} as Settings)).rejects.toThrow(
|
||||
'process.exit called',
|
||||
);
|
||||
|
||||
expect(mockConsoleError).toHaveBeenCalledWith(
|
||||
expect(mockWriteStderrLine).toHaveBeenCalledWith(
|
||||
expect.stringContaining('Invalid values:'),
|
||||
);
|
||||
|
||||
mockExit.mockRestore();
|
||||
mockConsoleError.mockRestore();
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -2138,17 +2119,14 @@ describe('Output format', () => {
|
|||
const mockExit = vi.spyOn(process, 'exit').mockImplementation(() => {
|
||||
throw new Error('process.exit called');
|
||||
});
|
||||
const mockConsoleError = vi
|
||||
.spyOn(console, 'error')
|
||||
.mockImplementation(() => {});
|
||||
mockWriteStderrLine.mockClear();
|
||||
await expect(parseArguments({} as Settings)).rejects.toThrow(
|
||||
'process.exit called',
|
||||
);
|
||||
expect(mockConsoleError).toHaveBeenCalledWith(
|
||||
expect(mockWriteStderrLine).toHaveBeenCalledWith(
|
||||
expect.stringContaining('Invalid values:'),
|
||||
);
|
||||
mockExit.mockRestore();
|
||||
mockConsoleError.mockRestore();
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -2172,23 +2150,19 @@ describe('parseArguments with positional prompt', () => {
|
|||
const mockExit = vi.spyOn(process, 'exit').mockImplementation(() => {
|
||||
throw new Error('process.exit called');
|
||||
});
|
||||
|
||||
const mockConsoleError = vi
|
||||
.spyOn(console, 'error')
|
||||
.mockImplementation(() => {});
|
||||
mockWriteStderrLine.mockClear();
|
||||
|
||||
await expect(parseArguments({} as Settings)).rejects.toThrow(
|
||||
'process.exit called',
|
||||
);
|
||||
|
||||
expect(mockConsoleError).toHaveBeenCalledWith(
|
||||
expect(mockWriteStderrLine).toHaveBeenCalledWith(
|
||||
expect.stringContaining(
|
||||
'Cannot use both a positional prompt and the --prompt (-p) flag together',
|
||||
),
|
||||
);
|
||||
|
||||
mockExit.mockRestore();
|
||||
mockConsoleError.mockRestore();
|
||||
});
|
||||
|
||||
it('should correctly parse a positional prompt to query field', async () => {
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@ export enum Command {
|
|||
PASTE_CLIPBOARD_IMAGE = 'pasteClipboardImage',
|
||||
|
||||
// App level bindings
|
||||
SHOW_ERROR_DETAILS = 'showErrorDetails',
|
||||
TOGGLE_TOOL_DESCRIPTIONS = 'toggleToolDescriptions',
|
||||
TOGGLE_IDE_CONTEXT_DETAIL = 'toggleIDEContextDetail',
|
||||
QUIT = 'quit',
|
||||
|
|
@ -156,7 +155,6 @@ export const defaultKeyBindings: KeyBindingConfig = {
|
|||
[Command.PASTE_CLIPBOARD_IMAGE]: [{ key: 'v', ctrl: true }],
|
||||
|
||||
// App level bindings
|
||||
[Command.SHOW_ERROR_DETAILS]: [{ key: 'o', ctrl: true }],
|
||||
[Command.TOGGLE_TOOL_DESCRIPTIONS]: [{ key: 't', ctrl: true }],
|
||||
[Command.TOGGLE_IDE_CONTEXT_DETAIL]: [{ key: 'g', ctrl: true }],
|
||||
[Command.QUIT]: [{ key: 'c', ctrl: true }],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue