mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Fix Headless Crash Tried to finish non-existent task with id (#46497)
Summary: Sometimes a headless task tries to finish, but it doesn’t exist, which causes an exception. No one knows how to reliably reproduce it, as it could be a race condition. However, if you attempt to remove a task that has already been removed, it shouldn’t cause an issue since you're trying to remove something that’s already gone (which is exactly what you want). Fixes: - https://github.com/facebook/react-native/issues/46496 - https://github.com/facebook/react-native/issues/33883 - https://github.com/facebook/react-native/issues/27597 - https://github.com/transistorsoft/react-native-background-fetch/issues/202 - https://github.com/transistorsoft/react-native-background-fetch/issues/369 - https://github.com/transistorsoft/react-native-background-geolocation/issues/2096 - https://github.com/jpush/jpush-react-native/issues/78 ## Stacktrace: ``` Fatal Exception: java.lang.AssertionError: Tried to finish non-existent task with id 28. at com.facebook.infer.annotation.Assertions.assertCondition(Assertions.java:88) at com.facebook.react.jstasks.HeadlessJsTaskContext.finishTask(HeadlessJsTaskContext.java:179) at com.facebook.react.jstasks.HeadlessJsTaskContext$3.run(HeadlessJsTaskContext.java:217) at android.os.Handler.handleCallback(Handler.java:958) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:257) at android.os.Looper.loop(Looper.java:368) at com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run(MessageQueueThreadImpl.java:233) at java.lang.Thread.run(Thread.java:1012) ``` ## Screenshot https://github.com/user-attachments/assets/101f0f53-95c9-40ec-a59d-22d6d474b457 ## Changelog: [ANDROID] [FIXED] - Fix Headless Crash `Tried to finish non-existent task with id` Pull Request resolved: https://github.com/facebook/react-native/pull/46497 Test Plan: I created an example where I attempt to remove a task that doesn’t exist. Example: https://github.com/RodolfoGS/react-native-fix-non-existent-task ### How to reproduce using the example above: 1. `git clone git@github.com:RodolfoGS/react-native-fix-non-existent-task.git` 2. `cd react-native-fix-non-existent-task` 3. `npm install` 4. `npm run android` 5. Notice the crash ### Steps to create the example from scratch and reproduce the crash: 1. `npx react-native-community/cli@latest init AwesomeProject` 2. `cd AwesomeProject` 3. Add call to finishTask to reproduce the crash (https://github.com/RodolfoGS/react-native-fix-non-existent-task/commit/6fe3c1388a58b9ffdcca5f9c6f00a4f2fea725ea) 4. `npm run android` 5. Notice the crash Reviewed By: javache Differential Revision: D62738059 Pulled By: rshest fbshipit-source-id: 3232dc76ba8a069279c2b741d62372537a3f9140
This commit is contained in:
committed by
Riccardo Cipolleschi
parent
83eb95e72a
commit
95021db72a
+13
-14
@@ -169,26 +169,25 @@ public class HeadlessJsTaskContext {
|
||||
|
||||
/**
|
||||
* Finish a JS task. Doesn't actually stop the task on the JS side, only removes it from the list
|
||||
* of active tasks and notifies listeners. A task can only be finished once.
|
||||
* of active tasks and notifies listeners.
|
||||
*
|
||||
* @param taskId the unique id returned by {@link #startTask}.
|
||||
*/
|
||||
public synchronized void finishTask(final int taskId) {
|
||||
Assertions.assertCondition(
|
||||
mActiveTasks.remove(taskId), "Tried to finish non-existent task with id " + taskId + ".");
|
||||
Assertions.assertCondition(
|
||||
mActiveTaskConfigs.remove(taskId) != null,
|
||||
"Tried to remove non-existent task config with id " + taskId + ".");
|
||||
boolean removed = mActiveTasks.remove(taskId);
|
||||
mActiveTaskConfigs.remove(taskId);
|
||||
removeTimeout(taskId);
|
||||
UiThreadUtil.runOnUiThread(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (HeadlessJsTaskEventListener listener : mHeadlessJsTaskEventListeners) {
|
||||
listener.onHeadlessJsTaskFinish(taskId);
|
||||
if (removed) {
|
||||
UiThreadUtil.runOnUiThread(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (HeadlessJsTaskEventListener listener : mHeadlessJsTaskEventListeners) {
|
||||
listener.onHeadlessJsTaskFinish(taskId);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void removeTimeout(int taskId) {
|
||||
|
||||
Reference in New Issue
Block a user