Skip to main content
Glama

1MCP Server

presetErrorHandler.test.ts15.5 kB
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { PresetError, PresetErrorHandler } from './presetErrorHandler.js'; describe('PresetError', () => { it('should create error with default options', () => { const error = new PresetError('Test error'); expect(error.name).toBe('PresetError'); expect(error.message).toBe('Test error'); expect(error.context).toBeUndefined(); expect(error.userMessage).toBeUndefined(); expect(error.exitCode).toBeUndefined(); expect(error.logLevel).toBe('error'); }); it('should create error with custom options', () => { const options = { context: 'test context', userMessage: 'User friendly message', exitCode: 42, logLevel: 'warn' as const, }; const error = new PresetError('Test error', options); expect(error.context).toBe('test context'); expect(error.userMessage).toBe('User friendly message'); expect(error.exitCode).toBe(42); expect(error.logLevel).toBe('warn'); }); }); describe('PresetErrorHandler', () => { beforeEach(() => { vi.clearAllMocks(); }); afterEach(() => { vi.restoreAllMocks(); }); describe('throwError', () => { it('should throw PresetError with message', () => { expect(() => { PresetErrorHandler.throwError('Test error'); }).toThrow(PresetError); expect(() => { PresetErrorHandler.throwError('Test error'); }).toThrow('Test error'); }); it('should throw PresetError with options', () => { const options = { context: 'test context', userMessage: 'User message', exitCode: 99, logLevel: 'warn' as const, }; try { PresetErrorHandler.throwError('Test error', options); expect.fail('Should have thrown an error'); } catch (error) { expect(error).toBeInstanceOf(PresetError); expect((error as PresetError).message).toBe('Test error'); expect((error as PresetError).context).toBe('test context'); expect((error as PresetError).userMessage).toBe('User message'); expect((error as PresetError).exitCode).toBe(99); expect((error as PresetError).logLevel).toBe('warn'); } }); }); describe('handleCliError', () => { it('should handle PresetError with user message', () => { const error = new PresetError('Internal error', { userMessage: 'Something went wrong', context: 'test context', exitCode: 42, }); expect(() => { PresetErrorHandler.handleCliError(error); }).toThrow('process.exit unexpectedly called with "42"'); }); it('should handle PresetError without user message', () => { const error = new PresetError('Internal error', { exitCode: 1, }); expect(() => { PresetErrorHandler.handleCliError(error); }).toThrow('process.exit unexpectedly called with "1"'); }); it('should handle PresetError with context parameter', () => { const error = new PresetError('Internal error'); expect(() => { PresetErrorHandler.handleCliError(error, 'additional context'); }).toThrow('process.exit unexpectedly called with "1"'); }); it('should handle regular Error', () => { const error = new Error('Regular error'); expect(() => { PresetErrorHandler.handleCliError(error); }).toThrow('process.exit unexpectedly called with "1"'); }); it('should handle regular Error with context', () => { const error = new Error('Regular error'); expect(() => { PresetErrorHandler.handleCliError(error, 'error context'); }).toThrow('process.exit unexpectedly called with "1"'); }); it('should handle unknown error type', () => { const error = 'string error'; expect(() => { PresetErrorHandler.handleCliError(error); }).toThrow('process.exit unexpectedly called with "1"'); }); it('should handle unknown error with context', () => { const error = { some: 'object' }; expect(() => { PresetErrorHandler.handleCliError(error, 'parsing'); }).toThrow('process.exit unexpectedly called with "1"'); }); }); describe('validationError', () => { it('should throw validation error without field', () => { try { PresetErrorHandler.validationError('Invalid input'); expect.fail('Should have thrown an error'); } catch (error) { expect(error).toBeInstanceOf(PresetError); expect((error as PresetError).message).toBe('Invalid input'); expect((error as PresetError).userMessage).toBe('Invalid input'); expect((error as PresetError).context).toBe('validation'); } }); it('should throw validation error with field', () => { try { PresetErrorHandler.validationError('must be string', 'name'); expect.fail('Should have thrown an error'); } catch (error) { expect(error).toBeInstanceOf(PresetError); expect((error as PresetError).message).toBe('must be string'); expect((error as PresetError).userMessage).toBe('Invalid name: must be string'); expect((error as PresetError).context).toBe('validation'); } }); it('should throw validation error with custom options', () => { try { PresetErrorHandler.validationError('Invalid', 'field', { context: 'custom context', exitCode: 99, }); expect.fail('Should have thrown an error'); } catch (error) { expect(error).toBeInstanceOf(PresetError); expect((error as PresetError).context).toBe('custom context'); expect((error as PresetError).exitCode).toBe(99); } }); }); describe('fileError', () => { it('should throw file read error', () => { const fileError = new Error('Permission denied'); try { PresetErrorHandler.fileError('read', '/path/to/file', fileError); expect.fail('Should have thrown an error'); } catch (error) { expect(error).toBeInstanceOf(PresetError); expect((error as PresetError).message).toBe('Failed to reading file: Permission denied'); expect((error as PresetError).context).toBe('file read'); expect((error as PresetError).userMessage).toBe('Could not reading preset file: /path/to/file'); expect((error as PresetError).exitCode).toBe(2); } }); it('should throw file write error', () => { const fileError = new Error('Disk full'); try { PresetErrorHandler.fileError('write', '/path/to/file', fileError); expect.fail('Should have thrown an error'); } catch (error) { expect(error).toBeInstanceOf(PresetError); expect((error as PresetError).message).toBe('Failed to writing file: Disk full'); expect((error as PresetError).context).toBe('file write'); expect((error as PresetError).userMessage).toBe('Could not writing preset file: /path/to/file'); } }); it('should throw file delete error', () => { const fileError = new Error('File not found'); try { PresetErrorHandler.fileError('delete', '/path/to/file', fileError); expect.fail('Should have thrown an error'); } catch (error) { expect(error).toBeInstanceOf(PresetError); expect((error as PresetError).message).toBe('Failed to deleting file: File not found'); expect((error as PresetError).context).toBe('file delete'); expect((error as PresetError).userMessage).toBe('Could not deleting preset file: /path/to/file'); } }); it('should handle unknown error in file operations', () => { const unknownError = 'string error'; try { PresetErrorHandler.fileError('read', '/path/to/file', unknownError); expect.fail('Should have thrown an error'); } catch (error) { expect(error).toBeInstanceOf(PresetError); expect((error as PresetError).message).toBe('Failed to reading file: Unknown error'); } }); }); describe('parseError', () => { it('should throw parse error', () => { const parseError = new Error('Syntax error at line 5'); try { PresetErrorHandler.parseError('invalid expression', parseError); expect.fail('Should have thrown an error'); } catch (error) { expect(error).toBeInstanceOf(PresetError); expect((error as PresetError).message).toBe('Failed to parse filter expression: Syntax error at line 5'); expect((error as PresetError).context).toBe('filter parsing'); expect((error as PresetError).userMessage).toBe('Invalid filter expression: "invalid expression"'); expect((error as PresetError).exitCode).toBe(1); } }); it('should throw parse error with custom options', () => { const parseError = new Error('Parse failed'); try { PresetErrorHandler.parseError('expression', parseError, { exitCode: 99, context: 'custom parsing', }); expect.fail('Should have thrown an error'); } catch (error) { expect(error).toBeInstanceOf(PresetError); expect((error as PresetError).exitCode).toBe(99); expect((error as PresetError).context).toBe('custom parsing'); } }); it('should handle unknown parse error', () => { const unknownError = { message: 'object error' }; try { PresetErrorHandler.parseError('expression', unknownError); expect.fail('Should have thrown an error'); } catch (error) { expect(error).toBeInstanceOf(PresetError); expect((error as PresetError).message).toBe('Failed to parse filter expression: Unknown error'); } }); }); describe('notFoundError', () => { it('should throw preset not found error', () => { try { PresetErrorHandler.notFoundError('preset', 'my-preset'); expect.fail('Should have thrown an error'); } catch (error) { expect(error).toBeInstanceOf(PresetError); expect((error as PresetError).message).toBe("preset 'my-preset' not found"); expect((error as PresetError).context).toBe('preset lookup'); expect((error as PresetError).userMessage).toBe('No preset found with name: my-preset'); expect((error as PresetError).exitCode).toBe(4); } }); it('should throw server not found error', () => { try { PresetErrorHandler.notFoundError('server', 'my-server'); expect.fail('Should have thrown an error'); } catch (error) { expect(error).toBeInstanceOf(PresetError); expect((error as PresetError).message).toBe("server 'my-server' not found"); expect((error as PresetError).context).toBe('server lookup'); } }); it('should throw config not found error', () => { try { PresetErrorHandler.notFoundError('config', 'my-config'); expect.fail('Should have thrown an error'); } catch (error) { expect(error).toBeInstanceOf(PresetError); expect((error as PresetError).message).toBe("config 'my-config' not found"); expect((error as PresetError).context).toBe('config lookup'); } }); it('should throw not found error with custom options', () => { try { PresetErrorHandler.notFoundError('preset', 'test', { exitCode: 99, userMessage: 'Custom message', }); expect.fail('Should have thrown an error'); } catch (error) { expect(error).toBeInstanceOf(PresetError); expect((error as PresetError).exitCode).toBe(99); expect((error as PresetError).userMessage).toBe('Custom message'); } }); }); describe('withErrorHandling', () => { it('should execute function successfully', () => { const fn = vi.fn().mockReturnValue('success'); const result = PresetErrorHandler.withErrorHandling(fn, 'test context'); expect(result).toBe('success'); expect(fn).toHaveBeenCalled(); }); it('should pass through PresetError', () => { const error = new PresetError('Original error'); const fn = vi.fn().mockImplementation(() => { throw error; }); expect(() => { PresetErrorHandler.withErrorHandling(fn, 'test context'); }).toThrow(error); }); it('should wrap regular errors', () => { const error = new Error('Regular error'); const fn = vi.fn().mockImplementation(() => { throw error; }); try { PresetErrorHandler.withErrorHandling(fn, 'test context'); expect.fail('Should have thrown an error'); } catch (wrappedError) { expect(wrappedError).toBeInstanceOf(PresetError); expect((wrappedError as PresetError).message).toBe('test context: Regular error'); expect((wrappedError as PresetError).context).toBe('test context'); } }); it('should handle unknown errors', () => { const error = 'string error'; const fn = vi.fn().mockImplementation(() => { throw error; }); try { PresetErrorHandler.withErrorHandling(fn, 'test context'); expect.fail('Should have thrown an error'); } catch (wrappedError) { expect(wrappedError).toBeInstanceOf(PresetError); expect((wrappedError as PresetError).message).toBe('test context: Unknown error'); } }); it('should use context from options when no context parameter', () => { const error = new Error('Regular error'); const fn = vi.fn().mockImplementation(() => { throw error; }); try { PresetErrorHandler.withErrorHandling(fn, undefined, { context: 'options context', exitCode: 99, }); expect.fail('Should have thrown an error'); } catch (wrappedError) { expect(wrappedError).toBeInstanceOf(PresetError); expect((wrappedError as PresetError).context).toBe('options context'); expect((wrappedError as PresetError).exitCode).toBe(99); } }); }); describe('createFilterError', () => { it('should display filter examples and throw parse error', () => { expect(() => { PresetErrorHandler.createFilterError('invalid filter'); }).toThrow('Failed to parse filter expression'); }); }); describe('logError', () => { it('should call logError without throwing', () => { const error = new PresetError('Test error', { context: 'test context', userMessage: 'User message', exitCode: 99, logLevel: 'warn', }); // Should not throw expect(() => { PresetErrorHandler.logError(error, 'additional context'); }).not.toThrow(); }); it('should handle regular Error without throwing', () => { const error = new Error('Regular error'); expect(() => { PresetErrorHandler.logError(error, 'context'); }).not.toThrow(); }); it('should handle unknown error without throwing', () => { const error = 'string error'; expect(() => { PresetErrorHandler.logError(error); }).not.toThrow(); }); it('should handle logger import failure gracefully', () => { const error = new Error('Test error'); expect(() => { PresetErrorHandler.logError(error); }).not.toThrow(); }); }); });

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/1mcp-app/agent'

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