Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions packages/common/ai/sessions/manage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,13 @@ export async function deleteAiSessionsForSite(
} catch {
// A placement can outlive its session file; still drop the metadata.
}
await deleteSharedSession( sessionId );
await deleteAiSessionPlacement( sessionId );
try {
await deleteSharedSession( sessionId );
await deleteAiSessionPlacement( sessionId );
} catch {
// Per-session best effort: one failed config write shouldn't
// abandon cleanup of the remaining sessions.
}
}
return sessionIds;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import fs from 'fs/promises';
import os from 'os';
import path from 'path';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { deleteAiSessionsForSite } from '@studio/common/ai/sessions/manage';
import {
readAiSessionPlacements,
setAiSessionSitePlacement,
} from '@studio/common/ai/sessions/placement';
import { createAiSession, listAiSessions } from '@studio/common/ai/sessions/store';
import * as sharedConfig from '@studio/common/lib/shared-config';
import { readSharedSessions, updateSharedSession } from '@studio/common/lib/shared-config';

// Runs against a real temp directory: DEV_CONFIG_DIR points app.json,
Expand Down Expand Up @@ -76,4 +77,32 @@ describe( 'deleteAiSessionsForSite', () => {
await expect( readAiSessionPlacements() ).resolves.toEqual( {} );
await expect( readSharedSessions() ).resolves.toEqual( {} );
} );

it( 'continues cleaning sessions when one shared config update fails', async () => {
const first = await createPlacedSession( 'site-1', '/sites/one' );
const second = await createPlacedSession( 'site-1', '/sites/one' );
await updateSharedSession( first.id, { archived: true } );
await updateSharedSession( second.id, { archived: true } );

const deleteSharedSession = vi
.spyOn( sharedConfig, 'deleteSharedSession' )
.mockRejectedValueOnce( new Error( 'Failed to write shared config.' ) );

try {
await deleteAiSessionsForSite( sessionsRoot, {
id: 'site-1',
path: '/sites/one',
} );
} finally {
deleteSharedSession.mockRestore();
}

await expect( listAiSessions( sessionsRoot ) ).resolves.toEqual( [] );
await expect( readAiSessionPlacements() ).resolves.toEqual( {
[ first.id ]: expect.objectContaining( { siteId: 'site-1' } ),
} );
await expect( readSharedSessions() ).resolves.toEqual( {
[ first.id ]: { archived: true },
} );
} );
} );