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

[$500] [Dev] Infinite receipt loading spinner with backend dev environment #44692

Closed
1 of 6 tasks
m-natarajan opened this issue Jul 1, 2024 · 35 comments
Closed
1 of 6 tasks
Assignees
Labels
Bug Something is broken. Auto assigns a BugZero manager. 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 Weekly KSv2

Comments

@m-natarajan
Copy link

m-natarajan commented Jul 1, 2024

If you haven’t already, check out our contributing guidelines for onboarding and email contributors@expensify.com to request to join our Slack channel!


Version Number:
Reproducible in staging?: Needs reproduction
Reproducible in production?: Needs reproduction
If this was caught during regression testing, add the test name, ID and link from TestRail:
Email or phone of affected tester (no customers):
Logs: https://stackoverflow.com/c/expensify/questions/4856
Expensify/Expensify Issue URL:
Issue reported by: @neil-marcellini
Slack conversation: https://expensify.slack.com/archives/C049HHMV9SM/p1719847597306219

Please dm @neil-marcellini on Slack during PDT hours if you would like to test against my dev env.

Action Performed:

  1. Open New Expensify running on a backend dev environment (ask an internal engineer to share theirs via ngrok)
  2. View an expense with a receipt

Expected Result:

Once the receipt is loaded there won't be a loading spinner

Actual Result:

Once the receipt is loaded there won't be a loading spinner

Workaround:

Unknown

Platforms:

Which of our officially supported platforms is this issue occurring on?

  • Android: Native
  • Android: mWeb Chrome
  • iOS: Native
  • iOS: mWeb Safari
  • MacOS: Chrome / Safari
  • MacOS: Desktop

Screenshots/Videos

Screen.Recording.2024-07-01.at.8.21.57.AM.mov

Add any screenshot/video evidence

View all open jobs on GitHub

Upwork Automation - Do Not Edit
  • Upwork Job URL: https://www.upwork.com/jobs/~014e28bd547489ae41
  • Upwork Job ID: 1807839133623941808
  • Last Price Increase: 2024-07-25
@m-natarajan m-natarajan added Daily KSv2 Needs Reproduction Reproducible steps needed Bug Something is broken. Auto assigns a BugZero manager. labels Jul 1, 2024
Copy link

melvin-bot bot commented Jul 1, 2024

Triggered auto assignment to @kadiealexander (Bug), see https://stackoverflow.com/c/expensify/questions/14418 for more details. Please add this bug to a GH project, as outlined in the SO.

@MelvinBot
Copy link

This has been labelled "Needs Reproduction". Follow the steps here: https://stackoverflowteams.com/c/expensify/questions/16989

@neil-marcellini neil-marcellini self-assigned this Jul 1, 2024
@neil-marcellini neil-marcellini added the External Added to denote the issue can be worked on by a contributor label Jul 1, 2024
Copy link

melvin-bot bot commented Jul 1, 2024

Job added to Upwork: https://www.upwork.com/jobs/~014e28bd547489ae41

@melvin-bot melvin-bot bot changed the title [Dev] Infinite receipt loading spinner with backend dev environment [$250] [Dev] Infinite receipt loading spinner with backend dev environment Jul 1, 2024
@melvin-bot melvin-bot bot added the Help Wanted Apply this label when an issue is open to proposals by contributors label Jul 1, 2024
Copy link

melvin-bot bot commented Jul 1, 2024

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

@Taiwrash
Copy link

Taiwrash commented Jul 1, 2024

Proposal

Please re-state the problem that we are trying to solve in this issue.

  • The spinner keep rolling after the receipt as loaded and currently not showing the image again

What is the root cause of that problem?

What changes do you think we should make in order to solve the problem?

  • Handle the state using the callback and memo correctly by updating the imageLoadedSuccessfully function with
const imageLoadedSuccessfully = useCallback(
    (event: {nativeEvent: ImageLoadEventData}) => {
        if (!onLoad) {
            return;
        }

        // We override `onLoad`, so both web and native have the same signature
        const source = event.nativeEvent.source;
        if (source && typeof source === 'object') {
            const {width, height} = source;
            onLoad({nativeEvent: {width, height}});
        } else {
            // Handle the case where source is undefined or not an object
            console.warn('Image source is undefined or not an object');
            onLoad({nativeEvent: {width: 0, height: 0}}); 
        }
    },
    [onLoad],
);

What alternative solutions did you explore? (Optional)

@ishpaul777
Copy link
Contributor

ishpaul777 commented Jul 1, 2024

This might be dupe of #44566, I can also reproduce with stag/prod server, setting USE_REACT_STRICT_MODE=false in CONFIG.js should resolve the issue temporarily.

@Taiwrash
Copy link

Taiwrash commented Jul 1, 2024

@ishpaul777 yes, it looks the same but I think for this demo, the app is not crashing which is different from the previous suggestion

@eh2077
Copy link
Contributor

eh2077 commented Jul 2, 2024

@Taiwrash Can you please elaborate on the root cause of this issue?

@Taiwrash
Copy link

Taiwrash commented Jul 3, 2024

YES!

The main cause of the error is the improper cleaning up of the data after fetching it from the backend. Although this can also be handled by setting the right dependencies for the useEffect where data fetching is happening. In summary, the root cause is the improper way of state update and wrong cleanup

@neil-marcellini
Copy link
Contributor

@Taiwrash thanks for elaborating. Would you please update your original proposal with links to the current code causing the root problem and explain exactly what the issue is, along with your proposed solution? Please see our contributing guidelines and you can also look at proposals on other issue to get an idea of how they are written.

Thanks @ishpaul777 for recommending setting USE_STRICT_MODE = false. I'll try that.

@neil-marcellini
Copy link
Contributor

This might be dupe of #44566,

Let's keep an eye on that one because it might have the same fix or root cause, but this feels a bit different so I'll keep it separate for now.

@neil-marcellini
Copy link
Contributor

Setting USE_REACT_STRICT_MODE: false in Config.ts doesn't seem to solve the problem.

@ishpaul777

This comment was marked as outdated.

@ishpaul777
Copy link
Contributor

ishpaul777 commented Jul 3, 2024

Sorry i take my words back its reproducable but USE_REACT_STRICT_MODE: false does solve it for me

Screen.Recording.2024-07-04.at.12.10.16.AM.mov

Copy link

melvin-bot bot commented Jul 5, 2024

@neil-marcellini, @kadiealexander, @eh2077 Uh oh! This issue is overdue by 2 days. Don't forget to update your issues!

@melvin-bot melvin-bot bot added the Overdue label Jul 5, 2024
@eh2077
Copy link
Contributor

eh2077 commented Jul 6, 2024

Still looking for proposals

@melvin-bot melvin-bot bot removed the Overdue label Jul 6, 2024
Copy link

melvin-bot bot commented Jul 8, 2024

📣 It's been a week! Do we have any satisfactory proposals yet? Do we need to adjust the bounty for this issue? 💸

@melvin-bot melvin-bot bot added the Overdue label Jul 8, 2024
@kadiealexander
Copy link
Contributor

@neil-marcellini does this still happen for you?

@neil-marcellini neil-marcellini changed the title [$250] [Dev] Infinite receipt loading spinner with backend dev environment [$500] [Dev] Infinite receipt loading spinner with backend dev environment Jul 9, 2024
Copy link

melvin-bot bot commented Jul 9, 2024

Upwork job price has been updated to $500

@Taiwrash
Copy link

Taiwrash commented Jul 9, 2024

Yes, and now the receipt images don't load at all. Let's double the price.

Do you have a new error when the receipt is not showing now?

Kindly help with screenshot or video of the current state. I am sorry i have been out on this issue before now

@melvin-bot melvin-bot bot added Reviewing Has a PR in review Weekly KSv2 and removed Daily KSv2 labels Jul 10, 2024
@Taiwrash
Copy link

Taiwrash commented Jul 10, 2024

I figured out the error is due to the failure to receive width properties from from the event.nativeEvent in some cases of the responses

const {width, height} = event.nativeEvent.source;

Here is a quick hack I came up to fix the issue for now

const imageLoadedSuccessfully = useCallback(
    (event: {nativeEvent: ImageLoadEventData}) => {
        if (!onLoad) {
            return;
        }

        // We override `onLoad`, so both web and native have the same signature
        const source = event.nativeEvent.source;
        if (source && typeof source === 'object') {
            const {width, height} = source;
            onLoad({nativeEvent: {width, height}});
        } else {
            // Handle the case where source is undefined or not an object
            console.warn('Image source is undefined or not an object');
            onLoad({nativeEvent: {width: 0, height: 0}}); 
        }
    },
    [onLoad],
);
  • The hacks: check source availability and is an object before destructuring.

@eh2077
Copy link
Contributor

eh2077 commented Jul 11, 2024

@Taiwrash Thanks for sharing your findings. Can you please update your proposal based on suggestion here #44692 (comment)

@Taiwrash
Copy link

Proposal

Updated

@melvin-bot melvin-bot bot added Daily KSv2 and removed Weekly KSv2 labels Jul 11, 2024
@Taiwrash
Copy link

@neil-marcellini @eh2077 looking forward to your review and besides i haven't been added to the slack channel, all the links i am seeing are not working for me. they are requesting for a unique email address

@eh2077
Copy link
Contributor

eh2077 commented Jul 12, 2024

@Taiwrash

Width value of the image is undefined and cannot be determined

Why does this keep images loading?

@Taiwrash
Copy link

Taiwrash commented Jul 12, 2024

@Taiwrash

Width value of the image is undefined and cannot be determined

Why does this keep images loading?

  1. The code is trying to access the width property of an object that is undefined. This is happening in the image loading callback
  2. The code is structure to use the loading spinner while waiting for images to load, the spinner's behaviour is tied to the successful completion of the image loading process which is not completing.
  3. The error has prevented the normal flow of the code that would otherwise signal that the image has finished loading, in other words, code to update the state of the spinner is not executed

Those are my observations @eh2077

@dominictb
Copy link
Contributor

dominictb commented Jul 13, 2024

Proposal

Please re-state the problem that we are trying to solve in this issue.

The receipt is infinitely loading in dev mode. In my machine it's the behavior is different from what I see in the evidence video: the image doesn't load at all. However, I believe all share the same root cause.

What is the root cause of that problem?

When enabling Strict Mode, React 18 simulates unmounting/mounting the component. Read more here. However, it seems like it doesn't re-create the ref during that simulation, and we'll have trouble with our patch for react-native-web's Image component.

During the unmount simulation, the image request will be cancelled here. However, since the ref is not re-created, in the next mount simulation this condition will hold true as the props.source is the same, hence, the
image will never be loaded. We can easily check the Network tab and see that the image request gets cancelled.

This also explains if we disable the strict mode, as there's no mount/unmount simulation, the request is never cancelled and we got the image loaded successfully.

What changes do you think we should make in order to solve the problem?

The idea is that if the request got cancelled during unmount/mount simulation, we should catch that and allows the request to be re-created during in the next mount. Details are below:

In here, introduce isCancelled function

isCancelled: () => abortController.signal.aborted

By default, in here, isCancelled() should always be true

+  var request = React.useRef({
+    cancel: () => {},
+    source: {
+      uri: '',
+      headers: {}
+    },
+    promise: Promise.resolve(''),
+.   isCancelled: () => true,
+  });

And in here, we should allow the request ref to be re-created (i.e: start a new image request) in case the current request is cancelled

if (!hasSourceDiff(nextSource, request.current.source) && !request.current.isCancelled()) {
   return;
}

What alternative solutions did you explore? (Optional)

N/A

@eh2077
Copy link
Contributor

eh2077 commented Jul 14, 2024

@dominictb Thank you for sharing your investigation!

@eh2077
Copy link
Contributor

eh2077 commented Jul 14, 2024

This might be dupe of #44566,

Let's keep an eye on that one because it might have the same fix or root cause, but this feels a bit different so I'll keep it separate for now.

@neil-marcellini I think we should put this on hold for #44566 as they're very likely to share the same root cause.

Setting USE_REACT_STRICT_MODE: false in Config.ts doesn't seem to solve the problem.

Now it solved the problem if USE_REACT_STRICT_MODE: false. It also didn’t work in my previous testing.

@kadiealexander kadiealexander changed the title [$500] [Dev] Infinite receipt loading spinner with backend dev environment [Hold for #44566] [$500] [Dev] Infinite receipt loading spinner with backend dev environment Jul 19, 2024
@kadiealexander kadiealexander added Weekly KSv2 and removed Daily KSv2 labels Jul 19, 2024
@neil-marcellini
Copy link
Contributor

This can be take off hold now. USE_REACT_STRICT_MODE: false does indeed fix the problem now, but it would be great to get this working with strict mode enabled too. @eh2077 @dominictb will your proposal work as is or do you need to make any updates now that the issue is off hold?

@neil-marcellini neil-marcellini changed the title [Hold for #44566] [$500] [Dev] Infinite receipt loading spinner with backend dev environment [$500] [Dev] Infinite receipt loading spinner with backend dev environment Jul 24, 2024
@neil-marcellini neil-marcellini removed Reviewing Has a PR in review Needs Reproduction Reproducible steps needed labels Jul 24, 2024
@eh2077
Copy link
Contributor

eh2077 commented Jul 25, 2024

There're some recent updates on patches/react-native-web+0.19.12+003+image-header-support.patch from PR https://github.com/Expensify/App/pull/45559/files. I think we need to diagnose the root cause again.

@dominictb Would you like to take a look into this?

Copy link

melvin-bot bot commented Jul 25, 2024

📣 It's been a week! Do we have any satisfactory proposals yet? Do we need to adjust the bounty for this issue? 💸

@dominictb
Copy link
Contributor

@eh2077 I think we can close this issue. That patch itself fix this problem as well. Thanks!

@neil-marcellini
Copy link
Contributor

Ah yeah, the problem is fixed after I double checked. Sweet!

I had to run this to get the package patch to apply properly.

npm cache clean --force
rm -rf node_modules
npm install

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Something is broken. Auto assigns a BugZero manager. 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 Weekly KSv2
Projects
None yet
Development

No branches or pull requests

8 participants