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

Inconsistent behavior in CodePush bundle vs default bundle when using mobx-state-tree state manager #2787

Open
leonardorib opened this issue Dec 12, 2024 · 1 comment

Comments

@leonardorib
Copy link

leonardorib commented Dec 12, 2024

Apparently there is an inconsistency in the behavior of the CodePush bundle in relation to the default bundle.

Issue description

In a mobx-state-tree (popular state manager) store action, when using try/catch/finally, if you hit the catch block and you have a return statement in this catch block, then you can't properly access the store self reference as you should be able to in the finally block.

This will only happen in CodePush bundles. It works normally in the default react-native bundle both in debug and release mode.

Minimal reproducible example app

https://github.com/leonardorib/codepush-issue-repro

There are video recordings available in the README file.

More details and examples

The project I'm working on uses mobx-state-tree as state manager and CodePush and I was faced with a scenario analogous to the following:

import {t} from 'mobx-state-tree';

const Store = t
  .model('Store', {
    someProp: t.optional(t.string, 'Hello World'),
  })

  .actions(self => ({
    setSomeProp(value: string) {
      self.someProp = value;
    },
    demonstrateIssueExecutingAction: (): void | null => {
      try {
        self.setSomeProp('demonstrateIssue try block');

        throw new Error('demonstrateIssue error'); // <--- Inducing an error to simulate something going wrong
      } catch (error) {
        // The issue only occurs when there is a return statement in the catch block
        // In this case we are returning void. But it could be null or anything else.
        // The result is the same.
        return; 
      } finally {
        try {
          // [ISSUE] This line will error out  ONLY in CodePush bundles with `TypeError: undefined is not a function`
          self.setSomeProp('demonstrateIssue finally block');
        } catch (error: any) {
          console.error(error);
        }
      }
    },
  }));

export const store = Store.create({});

Having a return statement in the catch block here should not cause any difference in behavior in the finally block. But it does, only in CodePush bundles.

An alternative would be directly mutating the property, which is fine in mobx-state-tree. But it also does not work in CodePush bundles:

 demonstrateIssueExecutingAction: (): void | null => {
      try {
        self.setSomeProp('demonstrateIssue try block');

        throw new Error('demonstrateIssue error');
      } catch (error) {
        return; // <-- If there is no return here, the issue does not occur
      } finally {
        // This won't error out, but the property won't be updated as it should
        // And again, only happens in CodePush bundles
        self.someProp = 'demonstrateIssue finally block';
      }
    },

Workaround

The workaround I could find was holding a reference to self:

demonstrateWorkaround: (): void | null => {
      const selfRef = self;
      try {
        self.setSomeProp('demonstrateWorkaround try block');

        throw new Error('demonstrateWorkaround error');
      } catch (error) {
        return null;
      } finally {
        // This will work properly even in CodePush bundles
          selfRef.setSomeProp('demonstrateWorkaround finally block');
      }
    },

So there is a workaround. But the problems here are:

  • The developer must know about this difference beforehand when relying on CodePush builds
  • If this is only a particular instance of a bigger problem, there might be other potential instances

Package versions / Environment

The minimal repro app I provided has everything on latest (RN 0.76.5 + react-native-code-push 9.0.0 + mobx 6.13.5 + mobx-state-tree 7.0.0 + mobx-react 9.2.0).

But I also tested this issue using RN 0.75.4 + react-native-code-push 8.2.1 + mobx 6.12.0 + mobx-state-tree 5.4.0 + mobx-react 7.6.0 with the same results.

Happens on both iOS and Android.

@MikhailSuendukov
Copy link
Contributor

Hello, and thank you for reaching out to us!

I attempted to reproduce the error using your demo project, but unfortunately, I was unable to reproduce it on my end. This issue might be related to your environment setup, or potentially a problem with the project bundle. Could you please double-check your configurations and, if possible, try reproducing the issue in a different environment?

To assist you further, we would need more details about your setup, including:

Your operating system and its version.
The versions of the iOS and Android SDKs you are using.
Providing this information will help us investigate the issue more effectively. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants