Logging Mechanisms and Error Handling Strategies in the SecureDesign VS Code Extension
SecureDesign implements a three-layer logging architecture using the Logger class and getLogger factory from react-vscode-webview-ipc/host, with structured error handling that propagates diagnostics to both VS Code output channels and the webview UI.
The SecureDesign VS Code extension embeds a hierarchical logging system that enables developers to trace runtime behavior from activation through individual tool executions. Understanding these logging mechanisms and error handling strategies is essential for diagnosing issues ranging from workspace configuration failures to AI service interactions. The architecture combines a global output channel with component-scoped loggers to provide granular visibility into extension operations.
Layered Logging Architecture
SecureDesign organizes logging into three distinct layers, each serving different observability needs across the extension's lifecycle.
Global Output Channel
The foundation of SecureDesign's logging system rests on the static Logger class imported from react-vscode-webview-ipc/host. During extension activation in src/extension.ts, the code binds this logger to a dedicated VS Code output pane:
Logger.setOutputChannel(vscode.window.createOutputChannel('SecureDesign'));
This static logger provides methods including error, warn, info, debug, setOutputChannel, and dispose. Once initialized, all high-level events—such as workspace folder detection failures or extension lifecycle changes—flow through this channel. For example, when no workspace folder is detected, the extension logs Logger.error('No workspace folder found for saving image') at line 27 of extension.ts.
Component-Scoped Loggers
For granular tracing within services and controllers, SecureDesign uses the getLogger(name) factory function, which returns an ILogger instance that prefixes all messages with the component name. In src/services/customAgentService.ts at line 49, the service initializes its logger:
private readonly logger = getLogger('CustomAgentService');
This pattern allows developers to filter logs by component when debugging specific subsystems. The ChatController similarly logs incoming and outgoing chat messages using a scoped instance, while FileWatcherService uses this approach to trace file system events.
Tool-Specific Loggers
Individual tools in the src/tools/ directory maintain their own loggers for execution tracing. The grep tool, implemented in src/tools/grep-tool.ts at line 14, demonstrates this pattern:
const logger = getLogger('grep tool');
These tool-level loggers capture execution details such as pattern matching parameters and result counts, enabling precise debugging of individual command executions without cluttering the global log stream.
Error Handling Strategies
SecureDesign employs consistent error handling strategies that prioritize logging before user notification, ensuring diagnostic context is preserved regardless of UI state.
Error Propagation Patterns
Errors follow a structured propagation path through the extension. When exceptions occur, the code first logs the error using Logger.error or the scoped logger.error, then handles display through one of two channels:
- Direct User Notification: Critical failures use
vscode.window.showErrorMessageto display modal or toast notifications. This pattern appears when workspace operations fail, combining the logger call with immediate visual feedback. - Webview Communication: For chat-related errors, the
ChatSidebarProvidersends error states back to the webview using itssendMessagemethod. This allows the UI to render error states within the chat panel itself, maintaining conversational context.
Graceful Resource Disposal
The extension implements defensive disposal patterns to prevent resource leaks. When the extension deactivates, Logger.dispose() flushes the output channel and releases resources (referenced at line 1422 of extension.ts). Services like FileWatcherService wrap disposal logic in try...catch blocks:
async dispose() {
try {
await this.watcher?.dispose();
this.logger.info('File watcher disposed');
} catch (e) {
this.logger.warn(`Error disposing file watcher: ${e}`);
}
}
This ensures that disposal failures are logged as warnings rather than crashing the deactivation sequence.
Implementation Examples
The following patterns demonstrate practical application of SecureDesign's logging and error handling:
Global Logger Usage in Extension Entry Point:
import { Logger } from 'react-vscode-webview-ipc/host';
Logger.setOutputChannel(vscode.window.createOutputChannel('SecureDesign'));
Logger.info('SecureDesign extension activated');
Service-Level Error Handling:
import { getLogger } from 'react-vscode-webview-ipc/host';
export class FileWatcherService {
private readonly logger = getLogger('FileWatcherService');
constructor() {
this.logger.debug('Initializing file watcher');
}
}
Tool Execution with Structured Error Return:
import { getLogger } from 'react-vscode-webview-ipc/host';
export async function grepTool(pattern: string, files: string[]) {
const logger = getLogger('grep tool');
logger.debug(`Running grep for "${pattern}"`);
try {
// Tool logic execution
logger.info(`Found ${matches.length} matches`);
return matches;
} catch (err) {
logger.error('Grep tool failed', err);
return { error: err instanceof Error ? err.message : String(err) };
}
}
Summary
- SecureDesign utilizes a three-tier logging architecture consisting of a global static
Logger, component-scoped loggers viagetLogger, and tool-specific instances for granular traceability. - The global output channel is established during extension activation in
src/extension.tsand captures high-level lifecycle events and workspace errors. - Error handling follows a consistent pattern: log first via
Logger.erroror scoped equivalents, then propagate to users through eithervscode.window.showErrorMessageor webview messaging viaChatSidebarProvider. - Resource disposal implements defensive
try...catchblocks with warning-level logging to ensure graceful shutdown without silent failures. - All logging infrastructure derives from the
react-vscode-webview-ipc/hostmodule, providing consistent API methods:error,warn,info,debug, anddispose.
Frequently Asked Questions
How do I view the SecureDesign extension logs?
Open the Output panel in VS Code (View > Output) and select SecureDesign from the dropdown menu. This channel captures all logs from the static Logger and scoped instances created via getLogger, with entries prefixed by component names for easy filtering.
What is the difference between Logger and getLogger in SecureDesign?
Logger is a static class used for global events and initialization-time logging, configured once via setOutputChannel in src/extension.ts. getLogger(name) returns an ILogger instance that prefixes all messages with the specified component name (e.g., 'CustomAgentService'), making it ideal for class-specific and tool-specific debugging contexts.
How does SecureDesign handle errors in tool executions?
Tools catch exceptions internally, log them using their scoped logger (e.g., logger.error('Grep tool failed', err)), and return structured error objects rather than throwing. This allows calling code in controllers to decide whether to display the error in the chat webview or handle it silently while preserving diagnostic information in the output channel.
Where should I add logging when extending SecureDesign's functionality?
Add component-scoped loggers using getLogger('YourComponentName') as private readonly fields in new services or controllers, following the pattern in src/services/customAgentService.ts. For high-level extension events (activation, configuration changes), use the static Logger imported from react-vscode-webview-ipc/host.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →