Skip to content

Commit 56a282c

Browse files
RodolfoGSblakef
authored andcommitted
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: - #46496 - #33883 - #27597 - transistorsoft/react-native-background-fetch#202 - transistorsoft/react-native-background-fetch#369 - transistorsoft/react-native-background-geolocation#2096 - jpush/jpush-react-native#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: #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 (RodolfoGS/react-native-fix-non-existent-task@6fe3c13) 4. `npm run android` 5. Notice the crash Reviewed By: javache Differential Revision: D62738059 Pulled By: rshest fbshipit-source-id: 3232dc76ba8a069279c2b741d62372537a3f9140
1 parent 366f1d0 commit 56a282c

File tree

1 file changed

+13
-14
lines changed

1 file changed

+13
-14
lines changed

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/jstasks/HeadlessJsTaskContext.java

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -169,26 +169,25 @@ public void run() {
169169

170170
/**
171171
* Finish a JS task. Doesn't actually stop the task on the JS side, only removes it from the list
172-
* of active tasks and notifies listeners. A task can only be finished once.
172+
* of active tasks and notifies listeners.
173173
*
174174
* @param taskId the unique id returned by {@link #startTask}.
175175
*/
176176
public synchronized void finishTask(final int taskId) {
177-
Assertions.assertCondition(
178-
mActiveTasks.remove(taskId), "Tried to finish non-existent task with id " + taskId + ".");
179-
Assertions.assertCondition(
180-
mActiveTaskConfigs.remove(taskId) != null,
181-
"Tried to remove non-existent task config with id " + taskId + ".");
177+
boolean removed = mActiveTasks.remove(taskId);
178+
mActiveTaskConfigs.remove(taskId);
182179
removeTimeout(taskId);
183-
UiThreadUtil.runOnUiThread(
184-
new Runnable() {
185-
@Override
186-
public void run() {
187-
for (HeadlessJsTaskEventListener listener : mHeadlessJsTaskEventListeners) {
188-
listener.onHeadlessJsTaskFinish(taskId);
180+
if (removed) {
181+
UiThreadUtil.runOnUiThread(
182+
new Runnable() {
183+
@Override
184+
public void run() {
185+
for (HeadlessJsTaskEventListener listener : mHeadlessJsTaskEventListeners) {
186+
listener.onHeadlessJsTaskFinish(taskId);
187+
}
189188
}
190-
}
191-
});
189+
});
190+
}
192191
}
193192

194193
private void removeTimeout(int taskId) {

0 commit comments

Comments
 (0)