From 3f0f307c222b587151d7069305d7bec50f780fe8 Mon Sep 17 00:00:00 2001 From: Scott Nonnenberg Date: Fri, 28 Feb 2025 10:01:58 +1000 Subject: [PATCH] Stories: Be resilient to a missing conversation --- ts/state/selectors/conversations.ts | 3 ++- ts/state/selectors/stories.ts | 15 +++++++++++++++ ts/util/findAndFormatContact.ts | 3 ++- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/ts/state/selectors/conversations.ts b/ts/state/selectors/conversations.ts index cb1d00f8e8..9fefa9c5d7 100644 --- a/ts/state/selectors/conversations.ts +++ b/ts/state/selectors/conversations.ts @@ -74,6 +74,7 @@ export type ConversationWithStoriesType = ConversationType & { }; let placeholderContact: ConversationType; +export const PLACEHOLDER_CONTACT_ID = 'placeholder-contact'; export const getPlaceholderContact = (): ConversationType => { if (placeholderContact) { return placeholderContact; @@ -82,7 +83,7 @@ export const getPlaceholderContact = (): ConversationType => { placeholderContact = { acceptedMessageRequest: false, badges: [], - id: 'placeholder-contact', + id: PLACEHOLDER_CONTACT_ID, type: 'direct', title: window.i18n('icu:unknownContact'), isMe: false, diff --git a/ts/state/selectors/stories.ts b/ts/state/selectors/stories.ts index 08bf0b43a3..9081069593 100644 --- a/ts/state/selectors/stories.ts +++ b/ts/state/selectors/stories.ts @@ -31,6 +31,7 @@ import { getConversationSelector, getHideStoryConversationIds, getMe, + PLACEHOLDER_CONTACT_ID, } from './conversations'; import { getUserConversationId } from './user'; import { getDistributionListSelector } from './storyDistributionLists'; @@ -189,6 +190,7 @@ export function getStoryView( readAt, timestamp, } = story; + const logId = `getStoryView/${timestamp}`; const { sendStateByConversationId } = story; let sendState: Array | undefined; @@ -200,8 +202,21 @@ export function getStoryView( Object.keys(sendStateByConversationId).forEach(recipientId => { const recipient = conversationSelector(recipientId); + if (recipient.id === PLACEHOLDER_CONTACT_ID) { + log.warn( + `${logId}: Found only placeholder contact for conversation ${recipientId}, skipping` + ); + return; + } const recipientSendState = sendStateByConversationId[recipient.id]; + if (!recipientSendState) { + log.warn( + `${logId}: No recipientSendState found for ${recipient.serviceId}, skipping.` + ); + return; + } + if (recipientSendState.status === SendStatus.Viewed) { innerViews += 1; } diff --git a/ts/util/findAndFormatContact.ts b/ts/util/findAndFormatContact.ts index ecdd168f95..1d472556fe 100644 --- a/ts/util/findAndFormatContact.ts +++ b/ts/util/findAndFormatContact.ts @@ -2,12 +2,13 @@ // SPDX-License-Identifier: AGPL-3.0-only import type { ConversationType } from '../state/ducks/conversations'; +import { PLACEHOLDER_CONTACT_ID } from '../state/selectors/conversations'; import { format, isValidNumber } from '../types/PhoneNumber'; const PLACEHOLDER_CONTACT: ConversationType = { acceptedMessageRequest: false, badges: [], - id: 'placeholder-contact', + id: PLACEHOLDER_CONTACT_ID, isMe: false, sharedGroupNames: [], title: window.i18n('icu:unknownContact'),