initial commit
This commit is contained in:
@@ -0,0 +1,191 @@
|
||||
import { ErrorHandler } from '../src/error-handler';
|
||||
import {
|
||||
OllamaError,
|
||||
ErrorType,
|
||||
NetworkError,
|
||||
ApiError,
|
||||
ValidationError,
|
||||
StreamingError,
|
||||
ToolExecutionError,
|
||||
PathValidationError,
|
||||
} from '../src/types';
|
||||
|
||||
// Mock Notice from Obsidian
|
||||
jest.mock('obsidian', () => ({
|
||||
Notice: jest.fn(),
|
||||
}));
|
||||
|
||||
describe('ErrorHandler', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
describe('handleError', () => {
|
||||
it('should handle OllamaError with user-friendly message', () => {
|
||||
const error = new NetworkError('Connection failed');
|
||||
ErrorHandler.handleError(error);
|
||||
expect(require('obsidian').Notice).toHaveBeenCalledWith(
|
||||
'Connection error. Please check if Ollama is running.'
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle generic Error with user-friendly message', () => {
|
||||
const error = new Error('Network timeout occurred');
|
||||
ErrorHandler.handleError(error);
|
||||
expect(require('obsidian').Notice).toHaveBeenCalledWith(
|
||||
'Request timed out. Please check your Ollama connection.'
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle unknown error type with generic message', () => {
|
||||
const error = 'some string error';
|
||||
ErrorHandler.handleError(error);
|
||||
expect(require('obsidian').Notice).toHaveBeenCalledWith('An unexpected error occurred');
|
||||
});
|
||||
|
||||
it('should log detailed error information to console', () => {
|
||||
const error = new Error('Test error');
|
||||
const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
ErrorHandler.handleError(error);
|
||||
expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Test error'));
|
||||
consoleSpy.mockRestore();
|
||||
});
|
||||
});
|
||||
|
||||
describe('NetworkError handling', () => {
|
||||
it('should create user-friendly message for network errors', () => {
|
||||
const error = new NetworkError('Connection failed');
|
||||
const message = ErrorHandler['getUserFriendlyMessage'](error);
|
||||
expect(message).toBe('Connection error. Please check if Ollama is running.');
|
||||
});
|
||||
|
||||
it('should include status code in error details', () => {
|
||||
const error = new NetworkError('Connection failed', 500);
|
||||
expect(error.statusCode).toBe(500);
|
||||
});
|
||||
});
|
||||
|
||||
describe('ValidationError handling', () => {
|
||||
it('should create user-friendly message for validation errors', () => {
|
||||
const error = new ValidationError('Invalid input', {
|
||||
field: 'path',
|
||||
message: 'Path is required',
|
||||
});
|
||||
const message = ErrorHandler['getUserFriendlyMessage'](error);
|
||||
expect(message).toContain('Invalid path');
|
||||
});
|
||||
|
||||
it('should handle validation errors without field details', () => {
|
||||
const error = new ValidationError('Invalid input');
|
||||
const message = ErrorHandler['getUserFriendlyMessage'](error);
|
||||
expect(message).toBe('Input validation error. Please correct your input.');
|
||||
});
|
||||
});
|
||||
|
||||
describe('StreamingError handling', () => {
|
||||
it('should create user-friendly message for streaming errors', () => {
|
||||
const error = new StreamingError('Response too long');
|
||||
const message = ErrorHandler['getUserFriendlyMessage'](error);
|
||||
expect(message).toBe('Response too long. Please try a shorter request.');
|
||||
});
|
||||
});
|
||||
|
||||
describe('ToolExecutionError handling', () => {
|
||||
it('should create user-friendly message for tool errors', () => {
|
||||
const error = new ToolExecutionError('Tool failed', 'create_file');
|
||||
const message = ErrorHandler['getUserFriendlyMessage'](error);
|
||||
expect(message).toContain('Tool error');
|
||||
expect(message).toContain('create_file');
|
||||
});
|
||||
});
|
||||
|
||||
describe('PathValidationError handling', () => {
|
||||
it('should create user-friendly message for path errors', () => {
|
||||
const error = new PathValidationError('Invalid path', '/../test.md');
|
||||
const message = ErrorHandler['getUserFriendlyMessage'](error);
|
||||
expect(message).toContain('Invalid file path');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Error creation methods', () => {
|
||||
it('should create NetworkError with proper type', () => {
|
||||
const error = ErrorHandler.createNetworkError('Connection failed');
|
||||
expect(error).toBeInstanceOf(NetworkError);
|
||||
expect(error.type).toBe(ErrorType.NETWORK_ERROR);
|
||||
});
|
||||
|
||||
it('should create ApiError with proper type', () => {
|
||||
const error = ErrorHandler.createApiError('API error');
|
||||
expect(error).toBeInstanceOf(ApiError);
|
||||
expect(error.type).toBe(ErrorType.API_ERROR);
|
||||
});
|
||||
|
||||
it('should create ValidationError with proper type', () => {
|
||||
const error = ErrorHandler.createValidationError('Validation failed', 'path');
|
||||
expect(error).toBeInstanceOf(ValidationError);
|
||||
expect(error.type).toBe(ErrorType.VALIDATION_ERROR);
|
||||
});
|
||||
|
||||
it('should create StreamingError with proper type', () => {
|
||||
const error = ErrorHandler.createStreamingError('Streaming failed');
|
||||
expect(error).toBeInstanceOf(StreamingError);
|
||||
expect(error.type).toBe(ErrorType.STREAMING_ERROR);
|
||||
});
|
||||
|
||||
it('should create ToolExecutionError with proper type', () => {
|
||||
const error = ErrorHandler.createToolExecutionError('Tool failed');
|
||||
expect(error).toBeInstanceOf(ToolExecutionError);
|
||||
expect(error.type).toBe(ErrorType.TOOL_EXECUTION_ERROR);
|
||||
});
|
||||
|
||||
it('should create PathValidationError with proper type', () => {
|
||||
const error = ErrorHandler.createPathValidationError('Path invalid');
|
||||
expect(error).toBeInstanceOf(PathValidationError);
|
||||
expect(error.type).toBe(ErrorType.PATH_VALIDATION_ERROR);
|
||||
});
|
||||
|
||||
it('should create UnknownError with proper type', () => {
|
||||
const error = ErrorHandler.createUnknownError('Unknown error');
|
||||
expect(error).toBeInstanceOf(OllamaError);
|
||||
expect(error.type).toBe(ErrorType.UNKNOWN_ERROR);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Error message detection', () => {
|
||||
it('should detect network-related errors in generic Error', () => {
|
||||
const error = new Error('Network connection failed');
|
||||
const message = ErrorHandler['getUserFriendlyMessageFromError'](error);
|
||||
expect(message).toContain('Connection error');
|
||||
});
|
||||
|
||||
it('should detect timeout errors in generic Error', () => {
|
||||
const error = new Error('Request timeout occurred');
|
||||
const message = ErrorHandler['getUserFriendlyMessageFromError'](error);
|
||||
expect(message).toContain('timed out');
|
||||
});
|
||||
|
||||
it('should detect validation errors in generic Error', () => {
|
||||
const error = new Error('Validation format error');
|
||||
const message = ErrorHandler['getUserFriendlyMessageFromError'](error);
|
||||
expect(message).toContain('Invalid input');
|
||||
});
|
||||
|
||||
it('should detect streaming errors in generic Error', () => {
|
||||
const error = new Error('Streaming chunk error');
|
||||
const message = ErrorHandler['getUserFriendlyMessageFromError'](error);
|
||||
expect(message).toContain('Response too long');
|
||||
});
|
||||
|
||||
it('should detect tool errors in generic Error', () => {
|
||||
const error = new Error('Tool function error');
|
||||
const message = ErrorHandler['getUserFriendlyMessageFromError'](error);
|
||||
expect(message).toContain('Tool execution error');
|
||||
});
|
||||
|
||||
it('should detect path errors in generic Error', () => {
|
||||
const error = new Error('Path file error');
|
||||
const message = ErrorHandler['getUserFriendlyMessageFromError'](error);
|
||||
expect(message).toContain('Invalid file path');
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user