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

Occasional Background task crash in production #61

Closed
stewartmcgown opened this issue Dec 16, 2020 · 18 comments · Fixed by #89
Closed

Occasional Background task crash in production #61

stewartmcgown opened this issue Dec 16, 2020 · 18 comments · Fixed by #89
Labels
bug Something isn't working help wanted Extra attention is needed released

Comments

@stewartmcgown
Copy link

My Sentry instance is catching occasional failures to start the background task.

https://sentry.ecoeats.uk/share/issue/7cf6f7ee88ee454ca3e73647693f83e3/

The issue appears to be that the buildNotification method constructs an Intent but the constructor returns null. I'm unable to replicate this issue in a dev environment.

notificationIntent = new Intent(context, context.getCurrentActivity().getClass());

Is the issue possibly that I'm attempting to start a task that is in the background already / the calling function is already in the background?

@Rapsssito
Copy link
Owner

@stewartmcgown, thanks for the feedback! It looks like the issue is that context.getCurrentActivity() returns null. However, I cannot debug the problem without any code to replicate the bug.

@stewartmcgown
Copy link
Author

This is the background task file!

const options = {
  taskName: "ecoeats",
  taskTitle: "ecoeats",
  taskDesc: "Waiting for orders!",
  taskIcon: {
    name: "ic_launcher",
    type: "mipmap",
  },
  color: theme.COLORS.PRIMARY,
  parameters: {
    delay: 10000,
  },
};


const veryIntensiveTask = async (
  taskDataArguments: typeof options["parameters"],
) => {
  while (true) {
    try {
      const store = useStore.getState();

      const online = store.online;
      const me = client.readQuery<MapType<Query, typeof ME>>({ query: GQL_ME });

      if (store.awaitingAccept) {
        playAlertSound();
        BackgroundService.updateNotification({
          taskTitle: "You have a new order!",
          taskDesc: "Open the app to accept.",
        });
        if (
          AppState.currentState === "background" ||
          AppState.currentState === "inactive"
        )
          PushNotification.localNotification({
            /* Android Only Properties */
            channelId: "order",

            bigText: "You have a new order!", // (optional) default: "message" prop
            subText: "Open the app to accept.", // (optional) default: none

            title: "You have a new order", // (optional)
            message: "Open the app to accept", // (required)
            timeoutAfter: taskDataArguments.delay,
          });
      } else {
        BackgroundService.updateNotification({
          taskTitle: "ecoeats",
          taskDesc: "Waiting for orders...",
        });
      }

      await client.query({
          query: GQL_HEARTBEAT,
          fetchPolicy: "no-cache",
          variables: {
            online,
          },
        });
      
    } catch (e) {
      captureException(e)
    }

    await new Promise((resolve) =>
      setTimeout(resolve, taskDataArguments.delay),
    );
  }
};

export const startHeartbeatTask = () => {
  BackgroundService.start(veryIntensiveTask, options);
  // iOS will also run everything here in the background until .stop() is called
  return () => BackgroundService.stop();
};

@Rapsssito
Copy link
Owner

@stewartmcgown, do you know what line is causing the error? If it is start(), stop() or updateNotification()

@Rapsssito Rapsssito added the bug Something isn't working label Dec 17, 2020
@stewartmcgown
Copy link
Author

I only know as much as you can see in the sentry crash report link. It doesn't seem to have any references to JS context at all!

@Rapsssito
Copy link
Owner

@stewartmcgown, could you try removing one of those instructions and check if the issue persists?

@stewartmcgown
Copy link
Author

The issue only appears sporadically in devices in the wild, so I'm afraid I can't really do much to test it and get any decent results. If somebody else encounters this issue and knows why, let us know!

@Rapsssito Rapsssito added help wanted Extra attention is needed work-in-progress and removed work-in-progress labels Dec 19, 2020
@AnagramEngineering
Copy link

AnagramEngineering commented Jan 4, 2021

I'm seeing mostly the same bug:

java.lang.RuntimeException: 
  at android.app.ActivityThread.handleServiceArgs (ActivityThread.java:4796)
  at android.app.ActivityThread.access$3100 (ActivityThread.java:308)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2346)
  at android.os.Handler.dispatchMessage (Handler.java:110)
  at android.os.Looper.loop (Looper.java:219)
  at android.app.ActivityThread.main (ActivityThread.java:8347)
  at java.lang.reflect.Method.invoke (Native Method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:513)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1055)
Caused by: java.lang.NullPointerException: 
  at android.app.PendingIntent.getActivity (PendingIntent.java:350)
  at android.app.PendingIntent.getActivity (PendingIntent.java:317)
  at com.asterinet.react.bgactions.RNBackgroundActionsTask.buildNotification (RNBackgroundActionsTask.java:40)
  at com.asterinet.react.bgactions.RNBackgroundActionsTask.onStartCommand (RNBackgroundActionsTask.java:80)
  at android.app.ActivityThread.handleServiceArgs (ActivityThread.java:4776)

currently only reported on an Huawei Mate 20 with Android 10 (SDK 29)

My code is a bit different though, as i start the background task when the app goes to background. It seems

getReactNativeHost().getReactInstanceManager().getCurrentReactContext()

returns null in that case. I now adapted the code a bit to see if that improves the behaviour, i'll come back to report if that is true.

@Bikash-Sawa
Copy link

I get error. Error: Attempt to invoke virtual method 'java.lang.Class java.lang.Object.getClass()' on a null object reference

when app is killed and and screen is off.

@stewartmcgown
Copy link
Author

For a bit of extra context, I've been able to trigger this via two different situations - both to do with restarting the app.

a) CodePush.restartApp() will occasionally trigger this

b) Restarting via the AlarmManager will cause this error every time unless a delay is added to the BackgroundService.start(....) call. I discovered this when implementing a periodic hard restart for our Kiosk app to prevent memory leaks over several months of operation.

e.g. code like this will trigger the background actions crash when the app is reinitialised.

 private void _restart() {
    Intent mStartActivity = new Intent(getCurrentActivity(), SplashActivity.class);
    int mPendingIntentId = 123456;
    PendingIntent mPendingIntent = PendingIntent.getActivity(mContext, mPendingIntentId,    mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT);
    AlarmManager mgr = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
    mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1000, mPendingIntent);
    System.exit(0);
  }

I've updated our call to background actions accordingly:

export const startHeartbeatTask = async () => {
  await BackgroundService.stop();

  /**
   * Why wait? When the app has been properly restarted via our
   * PhoenixModule, we need to make sure that the React context
   * has initialised properly before trying to re-attach the background
   * task to the activity.
   *
   * If we don't do that, we'll have serious problems and possibly
   * crashes on boot.
   *
   * This issue is slightly related.
   * https://github.com/Rapsssito/react-native-background-actions/issues/61
   *
   */
  setTimeout(() => BackgroundService.start(veryIntensiveTask, options), 10000);
  return () => BackgroundService.stop();
};

@Rapsssito
Copy link
Owner

@stewartmcgown, thanks for the reproducible code! It looks like an error when trying to access the React context while it is initialized. I will try to fix it ASAP.

@Rapsssito
Copy link
Owner

@stewartmcgown, I am not able to reproduce the issue, I am having issues restarting the app with AlarmManager. Could you provide a minimal reproducible React Native app?

@moyolvera
Copy link

moyolvera commented Apr 12, 2021

I'm also facing this issue. Unfortunately I haven't been able to reproduce it but crashlytics is showing a lot of this two errors:

Unable to start service : java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Class java.lang.Object.getClass()' on a null object reference

This first error is located on com.asterinet.react.bgactions.RNBackgroundActionsTask.buildNotification (RNBackgroundActionsTask.java:38)

Not allowed to start service Intent: app is in background

This last error seems to be located on com.asterinet.react.bgactions.BackgroundActionsModule.start (BackgroundActionsModule.java:53)

As I said i don't know what is causing this issues at this time is only happening on production

@ezranbayantemur
Copy link

I'm facing on this error too. I'm working on remote so can't produce it properly. Will you working on it soon @Rapsssito ? It would be great if you look at it 🙏

@Rapsssito
Copy link
Owner

@ezranbayantemur, I must be able to reproduce the issue in my local machine in order to fix it. If anyone could provide a reproducible code I would be able to start working on a fix.

@ezranbayantemur
Copy link

@Rapsssito I'll working on it on later day. Maybe I could provide a reproduceble code

@moyolvera
Copy link

My issue was related to CodePush, I found out that during installing the update the background action is failing to get access to the react context and that was causing the crashes, seems like preventing to run the background action if there's a pending update might fix the issue for me. More testing is needed to confirm that last statement

ArsalImam added a commit to raply-io/react-native-background-actions that referenced this issue May 24, 2021
@ArsalImam
Copy link
Contributor

@Rapsssito I have successfully verified the fix in #89 in the production environment (after 100% rollout - last week). Till now, we didn't receive any occurrence of this issue (currently, 2k+ users are using the latest version of the app).

Rapsssito pushed a commit that referenced this issue Jun 9, 2021
github-actions bot pushed a commit that referenced this issue Jun 9, 2021
## [2.6.1](v2.6.0...v2.6.1) (2021-06-09)

### Bug Fixes

* Fix [#61](#61) when React context was null ([2efefaa](2efefaa))
@github-actions
Copy link

github-actions bot commented Jun 9, 2021

🎉 This issue has been resolved in version 2.6.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working help wanted Extra attention is needed released
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants