| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- import { describe, it, expect, vi } from 'vitest'
- import { SttError, createErrorHandler, ErrorRecovery } from '../../src/core/stt-error'
- describe('SttError', () => {
- describe('constructor', () => {
- it('should create error with code and message', () => {
- const error = new SttError('NOT_INITIALIZED', 'SDK not initialized')
- expect(error).toBeInstanceOf(SttError)
- expect(error.name).toBe('SttError')
- expect(error.code).toBe('NOT_INITIALIZED')
- expect(error.message).toBe('SDK not initialized')
- expect(error.timestamp).toBeGreaterThan(0)
- expect(error.details).toBeUndefined()
- })
- it('should create error with details', () => {
- const details = { userId: 'test-user', channel: 'test-channel' }
- const error = new SttError('INVALID_CONFIG', 'Invalid configuration', details)
- expect(error.details).toEqual(details)
- })
- })
- describe('fromError', () => {
- it('should return SttError instance if already SttError', () => {
- const originalError = new SttError('NETWORK_ERROR', 'Network failed')
- const result = SttError.fromError(originalError)
- expect(result).toBe(originalError)
- })
- it('should convert Error to SttError', () => {
- const originalError = new Error('Something went wrong')
- const result = SttError.fromError(originalError, 'UNKNOWN_ERROR')
- expect(result).toBeInstanceOf(SttError)
- expect(result.code).toBe('UNKNOWN_ERROR')
- expect(result.message).toBe('Something went wrong')
- expect(result.details?.originalError).toBe(originalError)
- })
- it('should handle non-Error objects', () => {
- const result = SttError.fromError('String error', 'NETWORK_ERROR')
- expect(result).toBeInstanceOf(SttError)
- expect(result.code).toBe('NETWORK_ERROR')
- expect(result.message).toBe('String error')
- })
- })
- describe('toJSON', () => {
- it('should serialize error to JSON', () => {
- const error = new SttError('NOT_INITIALIZED', 'SDK not initialized')
- const json = error.toJSON()
- expect(json).toEqual({
- name: 'SttError',
- code: 'NOT_INITIALIZED',
- message: 'SDK not initialized',
- timestamp: error.timestamp,
- details: undefined,
- stack: error.stack,
- })
- })
- })
- describe('toString', () => {
- it('should return formatted string', () => {
- const error = new SttError('NOT_INITIALIZED', 'SDK not initialized')
- const str = error.toString()
- expect(str).toBe('[NOT_INITIALIZED] SDK not initialized')
- })
- })
- })
- describe('createErrorHandler', () => {
- it('should create error handler without emitter', () => {
- const handler = createErrorHandler()
- const error = new Error('Test error')
- const result = handler(error)
- expect(result).toBeInstanceOf(SttError)
- })
- it('should create error handler with emitter', () => {
- const emitter = {
- emit: vi.fn(),
- }
- const handler = createErrorHandler(emitter)
- const error = new Error('Test error')
- const result = handler(error)
- expect(result).toBeInstanceOf(SttError)
- expect(emitter.emit).toHaveBeenCalledWith('error', result)
- })
- it('should include context in details', () => {
- const handler = createErrorHandler()
- const error = new Error('Test error')
- const result = handler(error, 'test-context')
- expect(result.details?.context).toBe('test-context')
- })
- })
- describe('ErrorRecovery', () => {
- describe('retry', () => {
- it('should succeed on first attempt', async () => {
- const recovery = new ErrorRecovery()
- const operation = vi.fn().mockResolvedValue('success')
- const result = await recovery.retry(operation)
- expect(result).toBe('success')
- expect(operation).toHaveBeenCalledTimes(1)
- })
- it('should retry and succeed', async () => {
- const recovery = new ErrorRecovery()
- const operation = vi
- .fn()
- .mockRejectedValueOnce(new Error('First attempt failed'))
- .mockResolvedValueOnce('success')
- const result = await recovery.retry(operation)
- expect(result).toBe('success')
- expect(operation).toHaveBeenCalledTimes(2)
- })
- it('should fail after max retries', async () => {
- const recovery = new ErrorRecovery(2, 10)
- const operation = vi.fn().mockRejectedValue(new Error('Always fails'))
- await expect(recovery.retry(operation)).rejects.toThrow('Always fails')
- expect(operation).toHaveBeenCalledTimes(2) // Initial + 1 retry (maxRetries=2 means 2 total attempts)
- })
- it('should respect shouldRetry function', async () => {
- const recovery = new ErrorRecovery()
- const operation = vi.fn().mockRejectedValue(new SttError('NETWORK_ERROR', 'Network failed'))
- const shouldRetry = vi.fn().mockReturnValue(false)
- await expect(recovery.retry(operation, shouldRetry)).rejects.toThrow(SttError)
- expect(operation).toHaveBeenCalledTimes(1)
- expect(shouldRetry).toHaveBeenCalledTimes(1)
- })
- })
- })
|