Skip to main content
Glama
error-handling-logging.test.ts6.97 kB
/** * Error Handling and Logging Infrastructure Tests * * Tests for the comprehensive error handling, structured logging, and monitoring functionality */ import { MCPServer, ServerState, LogLevel, ErrorCategory, LoggerConfig } from '../server'; import { FormCreationTool } from '../tools'; import { TallyApiClientConfig } from '../services/TallyApiClient'; jest.mock('../tools'); describe('Error Handling and Logging Infrastructure', () => { let server: MCPServer; let testPort: number; beforeEach(async () => { // Use a random port to avoid conflicts testPort = 3000 + Math.floor(Math.random() * 1000); // Configure server with enhanced logging for testing const loggerConfig: Partial<LoggerConfig> = { level: LogLevel.DEBUG, enableConsole: true, enableStructured: true, redactSensitive: true, sensitiveFields: ['password', 'token', 'key', 'secret', 'authorization', 'cookie'], }; const dummyClientConfig: TallyApiClientConfig = { accessToken: 'test-key', }; server = new MCPServer({ port: testPort, debug: true, logger: loggerConfig, tools: { form_creation_tool: new FormCreationTool(dummyClientConfig), }, }); }); afterEach(async () => { if (server.getState() === ServerState.RUNNING) { await server.shutdown(); } }); describe('Structured Logging', () => { test('should support different log levels', async () => { const consoleSpy = jest.spyOn(console, 'log').mockImplementation(); // The log method is private but we can test through initialization await server.initialize(); // Verify console.log was called (indicates logging is working) expect(consoleSpy).toHaveBeenCalled(); consoleSpy.mockRestore(); }); test('should redact sensitive information', () => { // Test that the server has the redaction capability const config = server.getConfig(); expect(config.logger).toBeDefined(); // Test that sensitive fields are configured expect(config.logger?.sensitiveFields).toContain('password'); expect(config.logger?.sensitiveFields).toContain('token'); expect(config.logger?.sensitiveFields).toContain('secret'); }); test('should respect log level configuration', () => { const config = server.getConfig(); expect(config.logger?.level).toBeDefined(); expect(config.debug).toBe(true); }); }); describe('Error Metrics', () => { test('should track error metrics', () => { const errorMetrics = server.getErrorMetrics(); expect(errorMetrics).toHaveProperty('total'); expect(errorMetrics).toHaveProperty('byCategory'); expect(errorMetrics).toHaveProperty('byCode'); expect(typeof errorMetrics.total).toBe('number'); expect(typeof errorMetrics.byCategory).toBe('object'); expect(typeof errorMetrics.byCode).toBe('object'); }); test('should initialize with zero errors', () => { const errorMetrics = server.getErrorMetrics(); expect(errorMetrics.total).toBe(0); expect(Object.keys(errorMetrics.byCategory)).toHaveLength(0); expect(Object.keys(errorMetrics.byCode)).toHaveLength(0); }); }); describe('Logger Configuration', () => { test('should merge logger config with defaults', () => { const config = server.getConfig(); expect(config.logger).toBeDefined(); expect(config.logger?.enableConsole).toBe(true); expect(config.logger?.enableStructured).toBe(true); expect(config.logger?.redactSensitive).toBe(true); expect(config.logger?.component).toBe('MCPServer'); }); test('should have appropriate sensitive fields configured', () => { const config = server.getConfig(); const sensitiveFields = config.logger?.sensitiveFields || []; expect(sensitiveFields).toContain('password'); expect(sensitiveFields).toContain('token'); expect(sensitiveFields).toContain('key'); expect(sensitiveFields).toContain('secret'); expect(sensitiveFields).toContain('authorization'); expect(sensitiveFields).toContain('cookie'); }); }); describe('Error Categories', () => { test('should have all required error categories', () => { // Test that ErrorCategory enum has all expected values const expectedCategories = [ 'validation', 'authentication', 'authorization', 'network', 'timeout', 'rate_limit', 'internal', 'external', 'configuration', 'resource', ]; for (const category of expectedCategories) { expect(Object.values(ErrorCategory)).toContain(category); } }); }); describe('Integration with Health Monitoring', () => { test('should integrate error metrics with health monitoring', async () => { await server.initialize(); const healthMetrics = server.getHealthMetrics(); const errorMetrics = server.getErrorMetrics(); // Verify both systems are working expect(healthMetrics).toBeDefined(); expect(errorMetrics).toBeDefined(); // The error metrics should be accessible independently expect(typeof errorMetrics.total).toBe('number'); }); }); describe('Request Context Preservation', () => { test('should handle request ID generation', async () => { await server.initialize(); // Verify server is running and can handle the concept of request IDs expect(server.getState()).toBe(ServerState.RUNNING); // The server should be initialized with request handling capability expect(server.getConnectionCount()).toBe(0); }); }); describe('Server State Integration', () => { test('should maintain consistent state with enhanced logging', async () => { expect(server.getState()).toBe(ServerState.STOPPED); await server.initialize(); expect(server.getState()).toBe(ServerState.RUNNING); await server.shutdown(); expect(server.getState()).toBe(ServerState.STOPPED); }); }); describe('Backward Compatibility', () => { test('should maintain compatibility with existing functionality', async () => { // Test that all the original server functionality still works expect(server.getState).toBeDefined(); expect(server.getConnectionCount).toBeDefined(); expect(server.getConfig).toBeDefined(); expect(server.getHealthMetrics).toBeDefined(); expect(server.initialize).toBeDefined(); expect(server.shutdown).toBeDefined(); }); test('should support debug mode configuration', () => { const config = server.getConfig(); expect(config.debug).toBe(true); // Debug mode should affect logging behavior expect(config.logger?.level).toBe(LogLevel.DEBUG); }); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/learnwithcc/tally-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server