fix: prevent cascade rollback from restoring deleted session descendants (#1555)
The OpenCode server cascade-deletes all child sessions when a parent is removed. The client was sending individual DELETE requests for each descendant, which returned 404 after the parent's cascade removed them. The 404 triggered rollback in deleteSessionAction, restoring already- deleted sessions back into the global store. Changes: - executeDeleteSession: only send the root session delete; the server cascade handles descendants. - deleteSession / deleteSessionInDirectory: treat 404 in catch as success, acting as a safety net for remaining paths (e.g. sidebar bulk action bar when parent and child are both selected).
This commit is contained in:
@@ -214,16 +214,18 @@ export const useSessionActions = (args: Args) => {
|
||||
|
||||
const ids = [session.id, ...descendantIds];
|
||||
if (shouldHardDelete) {
|
||||
const { deletedIds, failedIds } = await args.deleteSessions(ids);
|
||||
if (deletedIds.length > 0) {
|
||||
toast.success(deletedIds.length === 1
|
||||
? t('sessions.sidebar.bulkActions.deletedSingle', { count: deletedIds.length })
|
||||
: t('sessions.sidebar.bulkActions.deletedPlural', { count: deletedIds.length }));
|
||||
}
|
||||
if (failedIds.length > 0) {
|
||||
toast.error(failedIds.length === 1
|
||||
? t('sessions.sidebar.bulkActions.failedDeleteSingle', { count: failedIds.length })
|
||||
: t('sessions.sidebar.bulkActions.failedDeletePlural', { count: failedIds.length }));
|
||||
// The server cascade-deletes all descendant sessions when the parent
|
||||
// is removed. Only send the root session delete request; sending
|
||||
// individual requests for each descendant would hit 404 (already
|
||||
// deleted by cascade) and trigger rollback that restores them.
|
||||
const success = await args.deleteSession(session.id);
|
||||
if (success) {
|
||||
const totalDeleted = descendantIds.length + 1;
|
||||
toast.success(totalDeleted === 1
|
||||
? t('sessions.sidebar.bulkActions.deletedSingle', { count: totalDeleted })
|
||||
: t('sessions.sidebar.bulkActions.deletedPlural', { count: totalDeleted }));
|
||||
} else {
|
||||
toast.error(t('sessions.sidebar.session.delete.error'));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -483,6 +483,12 @@ export async function deleteSession(sessionId: string, _options?: Record<string,
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error("[session-actions] deleteSession failed", error)
|
||||
// The server cascade-deletes child sessions when the parent is removed.
|
||||
// Subsequent delete attempts for those children return 404; treat as
|
||||
// success since the session was already deleted by the cascade.
|
||||
if ((error as { status?: number })?.status === 404) {
|
||||
return true
|
||||
}
|
||||
restoreSessionListSnapshots(snapshots)
|
||||
restoreGlobalSessionSnapshot(globalSnapshot)
|
||||
return false
|
||||
@@ -507,6 +513,9 @@ export async function deleteSessionInDirectory(sessionId: string, directory: str
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error("[session-actions] deleteSessionInDirectory failed", error)
|
||||
if ((error as { status?: number })?.status === 404) {
|
||||
return true
|
||||
}
|
||||
restoreSessionListSnapshots(snapshots)
|
||||
restoreGlobalSessionSnapshot(globalSnapshot)
|
||||
return false
|
||||
|
||||
Reference in New Issue
Block a user