Page MenuHomePhabricator

[lib] Extend RobotextParams to include parentThreadInfo
ClosedPublic

Authored by rohan on Sep 20 2023, 11:07 AM.
Tags
None
Referenced Files
Unknown Object (File)
Thu, May 16, 9:48 AM
Unknown Object (File)
Thu, May 16, 9:46 AM
Unknown Object (File)
Thu, May 16, 7:12 AM
Unknown Object (File)
Wed, May 15, 8:58 PM
Unknown Object (File)
Sun, May 12, 3:31 AM
Unknown Object (File)
Sun, May 12, 12:59 AM
Unknown Object (File)
Sun, May 12, 12:59 AM
Unknown Object (File)
Wed, May 8, 3:56 AM
Subscribers

Details

Summary

Currently, the app will crash if you attempt to create a sidebar from a CHANGE_ROLE robotext message. This is because when attempting to create the role, the threadInfo passed into robotextForMessageInfo from chat-selectors.js is undefined. The reason for this is in a pending sidebar, if you check the threadID, it is something like pending/sidebar/256|90231. Here, the 256|90231 corresponds to the source message that the sidebar is being created from, i.e. the message that the user clicks 'create thread' on.

To resolve this, we want to extend the RobotextParams to include a potentially null parentThreadInfo, and modify the call site in chat-selectors.js. To get the parentThreadInfo, we'd do the following:

  1. Parse out the source message ID from the pending sidebar thread ID
  2. Access messageStore.messages for the source message
  3. Read the threadID from the source message info
  4. Access the ThreadInfo from the threadInfos object using the newly found threadID

With this, we will now be able to access either the regular threadInfo or the parentThreadInfo in the CHANGE_ROLE message spec, no longer crashing the app. We can now re-allow sidebars to be created from CHANGE_ROLE messages as well.

One thing to note is the other callsite for robotextForMessageInfo is in getMessageTitle. Though when looking into what threadInfo is passed into it, it already receives the parentThreadInfo from createPendingSidebar. So I don't think we should have to update anything there.

This is @ashoat's suggestion (#5) addressing ENG-4981.

Test Plan
  1. Sending messages in parent threads still works
  2. Creating sidebars from non-robotext messages still works
  3. Creating sidebars from CHANGE_ROLE messages now works and no longer crashes
  4. Reloaded the app during the process of making a sidebar from a CHANGE_ROLE message (while it's pending) and it doesn't crash

Diff Detail

Repository
rCOMM Comm
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

lib/shared/message-utils.js
655 ↗(On Diff #31323)
  1. Let's rename this to use "sidebar" instead of "thread"
  2. Do we have any other functions that parse a pending sidebar ID?
lib/shared/messages/change-role-message-spec.js
133 ↗(On Diff #31323)

Hmm, I'm not sure this is the right check. After the thread is successfully created, won't threadInfo be created? At that point, it appears that you'll be trying to index into the threadInfo for a role that is actually from the parentThreadInfo

I would think you'd need to do something more like:

threadInfo.roles[messageInfo.newRole]?.name ?? parentThreadInfo.roles[messageInfo.newRole]?.name

That said, I would've figured that my concern would pop up in testing... so maybe I'm missing something?

ashoat requested changes to this revision.Sep 20 2023, 11:54 AM
ashoat added inline comments.
lib/shared/message-utils.js
77 ↗(On Diff #31323)

Have you updated all the callsites of this function to include parentThreadInfo? If not, how are you sure this is safe? Is there a possibility of robotextForMessageInfo being called from another context where parentThreadInfo will be missing, and then subsequently crashing in the same way it did before?

At a bare minimum, you should research all of the callsites (such as notif-utils.js) and add something to the Test Plan to cover each of them.

This revision now requires changes to proceed.Sep 20 2023, 11:54 AM
lib/shared/message-utils.js
77 ↗(On Diff #31323)

Call sites:

  • lib/selectors/chat-selectors.js --> the root cause of the crash, now addressed
  • lib/shared/message-utils.js --> covered this in the diff summary
  • lib/shared/notif-utils.js --> testing this now, will update this callsite with parentThreadInfo if I find that we need it, otherwise have it null

I think it would be good to at least pass in null or undefined as parentThreadInfo from the callsites that don't require parentThreadInfo (since they were working fine before). Regardless will test first then update

655 ↗(On Diff #31323)

Not that I'm aware of - the closest I could find was getPendingThreadID, but that just returns pending/sidebar/256|91092 for example, and parsePendingThreadID which returns something else

type PendingThreadIDContents = {
  +threadType: ThreadType,
  +memberIDs: $ReadOnlyArray<string>,
  +sourceMessageID: ?string,
};

I couldn't actually find a function that parses the numeric sidebar ID from the entire string (on a separate note, if I keep this function it'd make sense to move it to thread-utils close to these two)

lib/shared/messages/change-role-message-spec.js
133 ↗(On Diff #31323)

Yeah you're right, I checked threadStore to confirm and when the sidebar is created, the thread doesn't actually have the role info anymore.

The reason it's not crashing is because of the failsafe of lines 136-137, where if the threadInfo doesn't have the role, we parse it from the DB messageInfo.

lib/shared/message-utils.js
77 ↗(On Diff #31323)

Tested the following with notif-utils.js:

  • Ran the app on my physical phone
  • Ran through several scenarios of robotext notifs (change_role, change_thread_color, etc)
  • Confirmed on master that the threadInfo provided is non-null
  • Confirmed on this branch that the threadInfo provided is still non-null (this is expected since this was never the root cause of the problem)

The parentThreadInfo that addresses this crash is the 'fallback' option. so it makes sense that the non-problematic callsites will never need to fallback onto parentThreadInfo.

Going to at least update this diff to update non-problematic callsites to pass in a null as a third parameter, rather than not providing one at all.

Pass in null parameter from non-problematic call sites
(notifRobotextForMessageInfo and getMessageTitle)

ashoat requested changes to this revision.Sep 25 2023, 5:21 AM

It's generally an expectation that if you put a diff back on a reviewer's queue, you have addressed that reviewer's comments. If you haven't, you should at least attempt to explain why you're putting the diff back in that reviewer's queue (maybe you have a question?). Otherwise you should hit the "Plan Changes" button to keep it away from reviewers' queues until you've addressed all of the comments.

lib/shared/message-utils.js
655 ↗(On Diff #31323)

My point 1 here was never addressed

lib/shared/messages/change-role-message-spec.js
133 ↗(On Diff #31323)

This comment does not appear to have been addressed

This revision now requires changes to proceed.Sep 25 2023, 5:21 AM

One quick note: my original idea in ENG-4981 was to "extend RobotextParams to include a sidebar parent's ThreadInfo". In this case you appear to have extended it to include all threads' parents' ThreadInfo, which I think is probably better. I thought about whether we could save some work by reducing scope to my original proposal, but probably not. But if you think of something let me know.

lib/shared/message-utils.js
427 ↗(On Diff #31379)

I am skeptical of this. I get why it's technically okay... we don't need a message preview in this case because sidebars don't show a message preview in the ThreadList.

But think about what you're setting us up for. Let's imagine somebody adds message previewers for sidebars, or maybe somebody introduces a new message spec that relies on the parentThreadInfo parameter. They will have no idea of the complicated "contract" you've introduced here, where this info is only provided for certain cases. And what's worse is that they won't realize there's a problem until somebody coincidentally tries to do something with a CHANGE_ROLE message. Pretty much zero change that they'll think to specifically test that message type.

I don't think passing null in here is okay. Let's make sure we pass in the parentThreadInfo. This really should not be super hard... I see 3 callsites of getMessageTitle, 2 of which already have the parentThreadInfo, and the third is a hook where you can fetch it via useSelector.

lib/shared/notif-utils.js
274 ↗(On Diff #31379)

Similiar situation here. This is again "technically okay" because we never send a notif for a SIDEBAR_SOURCE, but that could change in the future.

notifRobotextForMessageInfo has 4 callsites, all of which are from the notificationTexts method of a message spec. One of them is changeRoleMessageSpec, which presents some risk.

After taking a look, I think we can add the parentThreadInfo here as well. We'll need to "drill" it through from keyserver/src/push/send.js to notificationTexts and then to this method. keyserver/src/push/send.js has access to the full list of threadInfos, so it should be as easy as threadInfos[threadInfo.parentThreadID].

lib/shared/notif-utils.js
274 ↗(On Diff #31379)

I've put up D9278, which should make this slightly easier for you

  1. Renamed parseSourceMessageIDFromPendingThreadID to parseSourceMessageIDFromPendingSidebarID
  2. Update the check in change-role-message-spec.js (I’d rather not throw an invariant here since we cover the unexpected case of roleName just simply being undefined in constructChangeRoleEntityText
  3. Pass in parentThreadInfo to robotextForMessageInfo from getMessageTitle
  4. Pass in parentThreadInfo to robotextForMessageInfo from notifRobotextForMessageInfo. Drill it from sendPushNotif —> notifTextsForMessageInfo —> fullNotifTextsForMessageInfo —> messageSpec.notificationTexts —> notifRobotextForMessageInfo
ashoat requested changes to this revision.Sep 25 2023, 8:33 AM

Thanks, this looks super close!!

lib/selectors/chat-selectors.js
534 ↗(On Diff #31404)

I don't think we need it to be this complicated. Can't we just do threadInfos[threadInfo.parentThreadID] like you did above? This would also allow us to skip the new parseSourceMessageIDFromPendingSidebarID utility

lib/shared/notif-utils.js
229 ↗(On Diff #31404)

Let's add parentThreadInfo to NotificationTextsParams rather than as its own param. This should mirror how we added it to RobotextParams

This revision now requires changes to proceed.Sep 25 2023, 8:33 AM

Simplify logic in chat-selectors.js and add parentThreadInfo to NotificationTextsParam

This revision is now accepted and ready to land.Sep 25 2023, 9:04 AM