import { describe, expect, it, vi } from 'vitest' import type { ConnectionConfig } from '../../../src/config/types.js' import { DriverDisposedError } from '../../../src/db/driver.js' import type { ManagedConnection } from '../../../src/db/manager.js' import { withManaged } from '../../../src/tools/managed.js' import { type FakeManager, fakeManager } from '../helpers.js' const config: ConnectionConfig = { name: 'c', type: 'postgres', host: 'h', user: 'u', readonly: false } const managed = (driver: ManagedConnection['driver']): ManagedConnection => ({ driver, config, source: 'store' }) describe('withManaged', () => { it('retries once when the driver was disposed under the caller', async () => { const manager: FakeManager = fakeManager() manager.get.mockResolvedValue(managed({} as ManagedConnection['driver'])) const fn = vi .fn() .mockRejectedValueOnce(new DriverDisposedError()) .mockResolvedValueOnce({ value: 42 }) const result = await withManaged(manager, 'c', fn) expect(result.isError).toBeFalsy() expect(JSON.parse((result.content[0] as { text: string }).text)).toEqual({ value: 42 }) expect(manager.get).toHaveBeenCalledTimes(2) expect(fn).toHaveBeenCalledTimes(2) }) it('gives up after a second DriverDisposedError', async () => { const manager: FakeManager = fakeManager() manager.get.mockResolvedValue(managed({} as ManagedConnection['driver'])) const fn = vi.fn().mockRejectedValue(new DriverDisposedError()) const result = await withManaged(manager, 'c', fn) expect(result.isError).toBe(true) expect((result.content[0] as { text: string }).text).toContain('being reconfigured') expect(manager.get).toHaveBeenCalledTimes(2) }) it('formats other driver errors with the engine prefix, no retry', async () => { const manager: FakeManager = fakeManager() manager.get.mockResolvedValue(managed({} as ManagedConnection['driver'])) const fn = vi.fn().mockRejectedValue(Object.assign(new Error('boom'), { code: '42P01' })) const result = await withManaged(manager, 'c', fn) expect(result.isError).toBe(true) expect((result.content[0] as { text: string }).text).toBe('[postgres 42P01] boom') expect(manager.get).toHaveBeenCalledTimes(1) }) it('returns manager errors plain without the engine prefix', async () => { const manager: FakeManager = fakeManager() manager.get.mockRejectedValue(new Error('no such connection')) const fn = vi.fn() const result = await withManaged(manager, 'c', fn) expect(result.isError).toBe(true) expect((result.content[0] as { text: string }).text).toBe('no such connection') expect(fn).not.toHaveBeenCalled() }) })