Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[$250] Investigate: 💥 Crash 💥 anonymous #11766

Closed
melvin-bot bot opened this issue Oct 12, 2022 · 8 comments
Closed

[$250] Investigate: 💥 Crash 💥 anonymous #11766

melvin-bot bot opened this issue Oct 12, 2022 · 8 comments
Assignees
Labels
Daily KSv2 External Added to denote the issue can be worked on by a contributor Help Wanted Apply this label when an issue is open to proposals by contributors

Comments

@melvin-bot
Copy link

melvin-bot bot commented Oct 12, 2022

Firebase has reported a new crash that we need to fix, here are all the details we found:

Non-fatal Exception: JavaScriptError

Cannot read property 'actionName' of undefined

main.jsbundle:1693:1257 line 1693 anonymous

Number of Crashes: 19

Device Information

  • Platforms: iOS, Android
  • App Versions: 1.2.13-2, 1.2.13.2, 1.2.21-4, 1.2.25.0
  • Devices: Apple iPhone10,1 15.6.1, Google sdk_gphone64_arm64 12, samsung SM-M315F 12, Apple iPhone11,6 16.0.0

Stacktraces

iOS 1.2.25.0
anonymous (/private/var/containers/Bundle/Application/7F77EEF4-9C23-4928-BFF2-5C55F8B84FA3/New Expensify.app/main.jsbundle:613:1068:613)
h (/private/var/containers/Bundle/Application/7F77EEF4-9C23-4928-BFF2-5C55F8B84FA3/New Expensify.app/main.jsbundle:2:1708:2)
d (/private/var/containers/Bundle/Application/7F77EEF4-9C23-4928-BFF2-5C55F8B84FA3/New Expensify.app/main.jsbundle:2:1151:2)
i (/private/var/containers/Bundle/Application/7F77EEF4-9C23-4928-BFF2-5C55F8B84FA3/New Expensify.app/main.jsbundle:2:497:2)
anonymous (/private/var/containers/Bundle/Application/7F77EEF4-9C23-4928-BFF2-5C55F8B84FA3/New Expensify.app/main.jsbundle:6:62:6)
h (/private/var/containers/Bundle/Application/7F77EEF4-9C23-4928-BFF2-5C55F8B84FA3/New Expensify.app/main.jsbundle:2:1708:2)
d (/private/var/containers/Bundle/Application/7F77EEF4-9C23-4928-BFF2-5C55F8B84FA3/New Expensify.app/main.jsbundle:2:1081:2)
i (/private/var/containers/Bundle/Application/7F77EEF4-9C23-4928-BFF2-5C55F8B84FA3/New Expensify.app/main.jsbundle:2:497:2)
global (/private/var/containers/Bundle/Application/7F77EEF4-9C23-4928-BFF2-5C55F8B84FA3/New Expensify.app/main.jsbundle:2935:4:2935)
iOS 1.2.25.0
anonymous (/private/var/containers/Bundle/Application/308D5C7E-5BCF-4157-A86E-EB3DD78B1915/New Expensify.app/main.jsbundle:613:960:613)
h (/private/var/containers/Bundle/Application/308D5C7E-5BCF-4157-A86E-EB3DD78B1915/New Expensify.app/main.jsbundle:2:1708:2)
d (/private/var/containers/Bundle/Application/308D5C7E-5BCF-4157-A86E-EB3DD78B1915/New Expensify.app/main.jsbundle:2:1151:2)
i (/private/var/containers/Bundle/Application/308D5C7E-5BCF-4157-A86E-EB3DD78B1915/New Expensify.app/main.jsbundle:2:497:2)
anonymous (/private/var/containers/Bundle/Application/308D5C7E-5BCF-4157-A86E-EB3DD78B1915/New Expensify.app/main.jsbundle:6:62:6)
h (/private/var/containers/Bundle/Application/308D5C7E-5BCF-4157-A86E-EB3DD78B1915/New Expensify.app/main.jsbundle:2:1708:2)
d (/private/var/containers/Bundle/Application/308D5C7E-5BCF-4157-A86E-EB3DD78B1915/New Expensify.app/main.jsbundle:2:1081:2)
i (/private/var/containers/Bundle/Application/308D5C7E-5BCF-4157-A86E-EB3DD78B1915/New Expensify.app/main.jsbundle:2:497:2)
global (/private/var/containers/Bundle/Application/308D5C7E-5BCF-4157-A86E-EB3DD78B1915/New Expensify.app/main.jsbundle:2935:4:2935)
iOS 1.2.25.0
anonymous (/private/var/containers/Bundle/Application/2FADF995-4C52-4B4C-A913-B655B3DBB419/New Expensify.app/main.jsbundle:613:954:613)
apply
anonymous (/private/var/containers/Bundle/Application/2FADF995-4C52-4B4C-A913-B655B3DBB419/New Expensify.app/main.jsbundle:77:1247:77)
k (/private/var/containers/Bundle/Application/2FADF995-4C52-4B4C-A913-B655B3DBB419/New Expensify.app/main.jsbundle:77:498:77)
callTimers (/private/var/containers/Bundle/Application/2FADF995-4C52-4B4C-A913-B655B3DBB419/New Expensify.app/main.jsbundle:77:2647:77)
apply
value (/private/var/containers/Bundle/Application/2FADF995-4C52-4B4C-A913-B655B3DBB419/New Expensify.app/main.jsbundle:42:3798:42)
anonymous (/private/var/containers/Bundle/Application/2FADF995-4C52-4B4C-A913-B655B3DBB419/New Expensify.app/main.jsbundle:42:674:42)
value (/private/var/containers/Bundle/Application/2FADF995-4C52-4B4C-A913-B655B3DBB419/New Expensify.app/main.jsbundle:42:2504:42)
value (/private/var/containers/Bundle/Application/2FADF995-4C52-4B4C-A913-B655B3DBB419/New Expensify.app/main.jsbundle:42:646:42)
Android 1.2.21-4
.anonymous
.loadModuleImplementation
.guardedLoadModule
.metroRequire
.anonymous
.loadModuleImplementation
.guardedLoadModule
.metroRequire
.anonymous
.loadModuleImplementation
.guardedLoadModule
.metroRequire
.global
Android 1.2.13-2
.anonymous
.anonymous
.each
.filter
.apply
.anonymous
.getSortedReportActions
.shouldComponentUpdate
.checkShouldComponentUpdate
.updateClassComponent
.beginWork
.performUnitOfWork
.workLoopSync
.renderRootSync
.performSyncWorkOnRoot
.flushSyncCallbacks
.scheduleUpdateOnFiber
.enqueueSetState
.anonymous
._loop
.keysChanged
.anonymous
.tryCallOne
.anonymous
.apply
.anonymous
._callTimer
._callReactNativeMicrotasksPass
.callReactNativeMicrotasks
.__callReactNativeMicrotasks
.anonymous
.__guard
.flushedQueue
.invokeCallbackAndReturnFlushedQueue
iOS 1.2.13.2
anonymous (/private/var/containers/Bundle/Application/813E41DB-B039-4CDA-83A8-219FCEA028FA/New Expensify.app/main.jsbundle:1693:1257:1693)
anonymous (/private/var/containers/Bundle/Application/813E41DB-B039-4CDA-83A8-219FCEA028FA/New Expensify.app/main.jsbundle:686:9883:686)
Ar (/private/var/containers/Bundle/Application/813E41DB-B039-4CDA-83A8-219FCEA028FA/New Expensify.app/main.jsbundle:686:9327:686)
Er (/private/var/containers/Bundle/Application/813E41DB-B039-4CDA-83A8-219FCEA028FA/New Expensify.app/main.jsbundle:686:9863:686)
apply
anonymous (/private/var/containers/Bundle/Application/813E41DB-B039-4CDA-83A8-219FCEA028FA/New Expensify.app/main.jsbundle:686:12744:686)
anonymous (/private/var/containers/Bundle/Application/813E41DB-B039-4CDA-83A8-219FCEA028FA/New Expensify.app/main.jsbundle:1693:1236:1693)
value (/private/var/containers/Bundle/Application/813E41DB-B039-4CDA-83A8-219FCEA028FA/New Expensify.app/main.jsbundle:2685:4309:2685)
Xt (/private/var/containers/Bundle/Application/813E41DB-B039-4CDA-83A8-219FCEA028FA/New Expensify.app/main.jsbundle:51:33335:51)
Cl (/private/var/containers/Bundle/Application/813E41DB-B039-4CDA-83A8-219FCEA028FA/New Expensify.app/main.jsbundle:51:57085:51)
Sa (/private/var/containers/Bundle/Application/813E41DB-B039-4CDA-83A8-219FCEA028FA/New Expensify.app/main.jsbundle:51:96855:51)
vi (/private/var/containers/Bundle/Application/813E41DB-B039-4CDA-83A8-219FCEA028FA/New Expensify.app/main.jsbundle:51:86900:51)
gi (/private/var/containers/Bundle/Application/813E41DB-B039-4CDA-83A8-219FCEA028FA/New Expensify.app/main.jsbundle:51:86802:51)
hi (/private/var/containers/Bundle/Application/813E41DB-B039-4CDA-83A8-219FCEA028FA/New Expensify.app/main.jsbundle:51:86567:51)
oi (/private/var/containers/Bundle/Application/813E41DB-B039-4CDA-83A8-219FCEA028FA/New Expensify.app/main.jsbundle:51:83487:51)
pt (/private/var/containers/Bundle/Application/813E41DB-B039-4CDA-83A8-219FCEA028FA/New Expensify.app/main.jsbundle:51:27333:51)
Za (/private/var/containers/Bundle/Application/813E41DB-B039-4CDA-83A8-219FCEA028FA/New Expensify.app/main.jsbundle:51:79771:51)
enqueueSetState (/private/var/containers/Bundle/Application/813E41DB-B039-4CDA-83A8-219FCEA028FA/New Expensify.app/main.jsbundle:51:32850:51)
anonymous (/private/var/containers/Bundle/Application/813E41DB-B039-4CDA-83A8-219FCEA028FA/New Expensify.app/main.jsbundle:21:1115:21)
c (/private/var/containers/Bundle/Application/813E41DB-B039-4CDA-83A8-219FCEA028FA/New Expensify.app/main.jsbundle:685:2782:685)
L (/private/var/containers/Bundle/Application/813E41DB-B039-4CDA-83A8-219FCEA028FA/New Expensify.app/main.jsbundle:685:3304:685)
anonymous (/private/var/containers/Bundle/Application/813E41DB-B039-4CDA-83A8-219FCEA028FA/New Expensify.app/main.jsbundle:685:7771:685)
tryCallOne (/Users/distiller/react-native/sdks/hermes/build_iphoneos/lib/InternalBytecode/InternalBytecode.js:53:16:53)
anonymous (/Users/distiller/react-native/sdks/hermes/build_iphoneos/lib/InternalBytecode/InternalBytecode.js:139:27:139)
apply
anonymous (/private/var/containers/Bundle/Application/813E41DB-B039-4CDA-83A8-219FCEA028FA/New Expensify.app/main.jsbundle:77:1662:77)
k (/private/var/containers/Bundle/Application/813E41DB-B039-4CDA-83A8-219FCEA028FA/New Expensify.app/main.jsbundle:77:498:77)
w (/private/var/containers/Bundle/Application/813E41DB-B039-4CDA-83A8-219FCEA028FA/New Expensify.app/main.jsbundle:77:888:77)
callReactNativeMicrotasks (/private/var/containers/Bundle/Application/813E41DB-B039-4CDA-83A8-219FCEA028FA/New Expensify.app/main.jsbundle:77:3055:77)
value (/private/var/containers/Bundle/Application/813E41DB-B039-4CDA-83A8-219FCEA028FA/New Expensify.app/main.jsbundle:42:2868:42)
anonymous (/private/var/containers/Bundle/Application/813E41DB-B039-4CDA-83A8-219FCEA028FA/New Expensify.app/main.jsbundle:42:960:42)
value (/private/var/containers/Bundle/Application/813E41DB-B039-4CDA-83A8-219FCEA028FA/New Expensify.app/main.jsbundle:42:2504:42)
value (/private/var/containers/Bundle/Application/813E41DB-B039-4CDA-83A8-219FCEA028FA/New Expensify.app/main.jsbundle:42:919:42)
value (/private/var/containers/Bundle/Application/813E41DB-B039-4CDA-83A8-219FCEA028FA/New Expensify.app/main.jsbundle:42:854:42)

Internal Firebase Info

💥 DO NOT EDIT THIS SECTION 💥

Crash IDs: fd1cdb4e916b7497e85f0e22ad937c6e, 29f5a4afa1f0968901244363906bf119, 0c9127e6df526e091a2c1234b473af9b, 687215b1c83475a4093a48662b02c853, 0c1548b4c6419659a1549900f4f1180a, c3295e2f33bd1e110d971c0a7f959cf0
Exception: Cannot read property 'actionName' of undefined

REMINDER: Typically, Firebase Crashlytics issues should be capped at $500.

@melvin-bot melvin-bot bot added Daily KSv2 External Added to denote the issue can be worked on by a contributor labels Oct 12, 2022
@melvin-bot
Copy link
Author

melvin-bot bot commented Oct 12, 2022

Triggered auto assignment to @maddylewis (External), see https://stackoverflow.com/c/expensify/questions/8582 for more details.

@melvin-bot
Copy link
Author

melvin-bot bot commented Oct 12, 2022

Triggered auto assignment to Contributor-plus team member for initial proposal review - @sobitneupane (External)

@melvin-bot melvin-bot bot added the Help Wanted Apply this label when an issue is open to proposals by contributors label Oct 12, 2022
@melvin-bot
Copy link
Author

melvin-bot bot commented Oct 12, 2022

Triggered auto assignment to @sketchydroide (External), see https://stackoverflow.com/c/expensify/questions/7972 for more details.

@melvin-bot melvin-bot bot changed the title Investigate: 💥 Crash 💥 anonymous [$250] Investigate: 💥 Crash 💥 anonymous Oct 12, 2022
@hungvu193
Copy link
Contributor

hungvu193 commented Oct 12, 2022

Proposal
Since we didn't know exactly where it happened, the best way to fix and avoid this bug is to add null safety where we got the .actionName.

function isConsecutiveActionMadeByPreviousActor(reportActions, actionIndex) {
const previousAction = reportActions[actionIndex + 1];
const currentAction = reportActions[actionIndex];
// It's OK for there to be no previous action, and in that case, false will be returned
// so that the comment isn't grouped
if (!currentAction || !previousAction) {
return false;
}
// Comments are only grouped if they happen within 5 minutes of each other
if (currentAction.action.timestamp - previousAction.action.timestamp > 300) {
return false;
}
// Do not group if previous or current action was a renamed action
if (previousAction.action.actionName === CONST.REPORT.ACTIONS.TYPE.RENAMED
|| currentAction.action.actionName === CONST.REPORT.ACTIONS.TYPE.RENAMED) {
return false;
}

App/src/libs/ReportUtils.js

Lines 105 to 112 in 9b15fbc

function canEditReportAction(reportAction) {
return reportAction.actorEmail === sessionEmail
&& reportAction.reportActionID
&& reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT
&& !isReportMessageAttachment(lodashGet(reportAction, ['message', 0], {}))
&& reportAction.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD
&& reportAction.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE;
}

App/src/libs/ReportUtils.js

Lines 122 to 128 in 9b15fbc

function canDeleteReportAction(reportAction) {
return reportAction.actorEmail === sessionEmail
&& reportAction.reportActionID
&& reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT
&& reportAction.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD
&& reportAction.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE;
}

if (this.props.action.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED) {
return <ReportActionItemCreated reportID={this.props.report.reportID} />;
}
if (this.props.action.actionName === CONST.REPORT.ACTIONS.TYPE.RENAMED) {
return <RenameAction action={this.props.action} />;
}
let children;
if (this.props.action.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) {
children = (

Solution
Use lodashGet to make sure we got the value from object that we got the actionName property.

From bb77413433d3277386a92ffe196c1d57c1b1951a Mon Sep 17 00:00:00 2001
From: Hans <hungvu193@users.noreply.github.com>
Date: Wed, 12 Oct 2022 23:40:26 +0700
Subject: [PATCH] add action name null safety

---
 src/libs/ReportActionsUtils.js                          | 4 ++++
 src/libs/ReportUtils.js                                 | 6 ++++++
 src/pages/home/report/ContextMenu/ContextMenuActions.js | 2 +-
 src/pages/home/report/ReportActionItem.js               | 8 +++++---
 4 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/src/libs/ReportActionsUtils.js b/src/libs/ReportActionsUtils.js
index 6616d0351..0faed5e3a 100644
--- a/src/libs/ReportActionsUtils.js
+++ b/src/libs/ReportActionsUtils.js
@@ -83,6 +83,10 @@ function isConsecutiveActionMadeByPreviousActor(reportActions, actionIndex) {
         return false;
     }
 
+    if (!currentAction.action || !previousAction.action) {
+        return false;
+    }
+
     // Comments are only grouped if they happen within 5 minutes of each other
     if (currentAction.action.timestamp - previousAction.action.timestamp > 300) {
         return false;
diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js
index 94bf06fc2..726aa04c1 100644
--- a/src/libs/ReportUtils.js
+++ b/src/libs/ReportUtils.js
@@ -103,6 +103,9 @@ function sortReportsByLastVisited(reports) {
  * @returns {Boolean}
  */
 function canEditReportAction(reportAction) {
+    if (!reportAction) {
+        return false;
+    }
     return reportAction.actorEmail === sessionEmail
         && reportAction.reportActionID
         && reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT
@@ -120,6 +123,9 @@ function canEditReportAction(reportAction) {
  * @returns {Boolean}
  */
 function canDeleteReportAction(reportAction) {
+    if (!reportAction) {
+        return false;
+    }
     return reportAction.actorEmail === sessionEmail
         && reportAction.reportActionID
         && reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT
diff --git a/src/pages/home/report/ContextMenu/ContextMenuActions.js b/src/pages/home/report/ContextMenu/ContextMenuActions.js
index 7d84a9b31..0a83dbd84 100644
--- a/src/pages/home/report/ContextMenu/ContextMenuActions.js
+++ b/src/pages/home/report/ContextMenu/ContextMenuActions.js
@@ -88,7 +88,7 @@ export default [
         icon: Expensicons.Clipboard,
         successTextTranslateKey: 'reportActionContextMenu.copied',
         successIcon: Expensicons.Checkmark,
-        shouldShow: (type, reportAction) => (type === CONTEXT_MENU_TYPES.REPORT_ACTION
+        shouldShow: (type, reportAction) => (type === CONTEXT_MENU_TYPES.REPORT_ACTION && !!reportAction
             && reportAction.actionName !== CONST.REPORT.ACTIONS.TYPE.IOU
             && !ReportUtils.isReportMessageAttachment(_.last(lodashGet(reportAction, ['message'], [{}])))),
 
diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js
index 6c6a85269..b4b21edf6 100644
--- a/src/pages/home/report/ReportActionItem.js
+++ b/src/pages/home/report/ReportActionItem.js
@@ -126,15 +126,17 @@ class ReportActionItem extends Component {
     }
 
     render() {
-        if (this.props.action.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED) {
+        const actionName = lodashGet(this.props, 'action.actionName', '');
+
+        if (actionName === CONST.REPORT.ACTIONS.TYPE.CREATED) {
             return <ReportActionItemCreated reportID={this.props.report.reportID} />;
         }
-        if (this.props.action.actionName === CONST.REPORT.ACTIONS.TYPE.RENAMED) {
+        if (actionName === CONST.REPORT.ACTIONS.TYPE.RENAMED) {
             return <RenameAction action={this.props.action} />;
         }
 
         let children;
-        if (this.props.action.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) {
+        if (actionName === CONST.REPORT.ACTIONS.TYPE.IOU) {
             children = (
                 <IOUAction
                     chatReportID={this.props.report.reportID}
-- 
2.31.0


@Uros787
Copy link
Contributor

Uros787 commented Oct 12, 2022

Proposal

Based on stacktrace we can see that the error appeared in getSortedReportActions
in ReportActionUtils.js

Solution:
Add value checking for every actionName in getSortedReportActions
Screenshot 2022-10-12 at 19 15 23

@aimane-chnaif
Copy link
Contributor

This is duplicated with #11754 and will be fixed internally. So can be closed

@sobitneupane
Copy link
Contributor

Yes. It looks similar. We can close this issue as the fix is already deployed to staging.

@maddylewis maddylewis assigned maddylewis and unassigned maddylewis Oct 14, 2022
@maddylewis
Copy link
Contributor

based on #11766 (comment), closing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Daily KSv2 External Added to denote the issue can be worked on by a contributor Help Wanted Apply this label when an issue is open to proposals by contributors
Projects
None yet
Development

No branches or pull requests

6 participants