From 55e34b5f9a1ba002b275f32dff57286b59769ac2 Mon Sep 17 00:00:00 2001 From: Carlos Valente Date: Mon, 14 Jul 2025 06:03:19 +0200 Subject: [PATCH] fix: guard corrupted parent on delete --- apps/client/src/common/hooks/useEntryAction.ts | 8 ++++++-- apps/server/src/api-data/rundown/rundown.dao.ts | 13 +++++++++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/apps/client/src/common/hooks/useEntryAction.ts b/apps/client/src/common/hooks/useEntryAction.ts index 8bd9c9350..0ee338b1f 100644 --- a/apps/client/src/common/hooks/useEntryAction.ts +++ b/apps/client/src/common/hooks/useEntryAction.ts @@ -808,8 +808,12 @@ function optimisticDeleteEntries(entryIds: EntryId[], rundown: Rundown) { if (isOntimeBlock(entry) || !entry.parent) { order = order.filter((id) => id !== entry.id); } else { - const parent = entries[entry.parent] as OntimeBlock; - parent.entries = parent.entries.filter((parentEntry) => parentEntry !== entry.id); + const parent = entries[entry.parent]; + if ('parent' in entries) { + (parent as OntimeBlock).entries = (parent as OntimeBlock).entries.filter( + (parentEntry) => parentEntry !== entry.id, + ); + } } delete entries[entry.id]; diff --git a/apps/server/src/api-data/rundown/rundown.dao.ts b/apps/server/src/api-data/rundown/rundown.dao.ts index 5476464f7..0466dc3bd 100644 --- a/apps/server/src/api-data/rundown/rundown.dao.ts +++ b/apps/server/src/api-data/rundown/rundown.dao.ts @@ -40,6 +40,7 @@ import { getUniqueId, } from './rundown.utils.js'; import { makeRundownMetadata, ProcessedRundownMetadata } from './rundown.parser.js'; +import { consoleError } from '../../utils/console.js'; /** * The currently loaded rundown in cache @@ -243,8 +244,16 @@ function remove(rundown: Rundown, entry: OntimeEntry) { } } else if (entry.parent) { // at this point, we are handling entries inside a block, so we need to remove the reference - const parentBlock = rundown.entries[entry.parent] as OntimeBlock; - if (parentBlock) { + const parentBlock = rundown.entries[entry.parent]; + + // eslint-disable-next-line no-unused-labels -- dev code path + DEV: { + if (parentBlock && !isOntimeBlock(parentBlock)) { + consoleError(`Parent block with ID ${entry.parent} is not a valid OntimeBlock`); + } + } + + if (parentBlock && isOntimeBlock(parentBlock)) { // we call a mutation to the parent event to remove the entry from the events const filteredEvents = deleteById(parentBlock.entries, entry.id); edit(rundown, { id: parentBlock.id, entries: filteredEvents });