Skip to content

Cancel pending PeerTube instance request when its view is destroyed - #13927

Open
Huge wants to merge 1 commit into
TeamNewPipe:devfrom
Huge:fix/peertube-add-instance-lifecycle
Open

Huge wants to merge 1 commit into
TeamNewPipe:devfrom
Huge:fix/peertube-add-instance-lifecycle

Conversation

@Huge

@Huge Huge commented Oct 17, 2026 •

Copy link
Copy Markdown

What is it?

  • Bugfix (user facing)
  • Feature (user facing)
  • Codebase improvement (dev facing)
  • Meta improvement to the project (dev facing)

Description of the changes in your PR

  • PeertubeInstanceListFragment.addInstance() hides binding.loadingProgressBar when the instance request finishes, but the request was only disposed in onDestroy(), while onDestroyView() already sets binding to null. The disposables are now cleared in onDestroyView(), so the request ends together with the view it updates.
  • A correction to my report in NullPointerException in PeertubeInstanceListFragment.addInstance() due to Rx callback after onDestroyView() #13871: pressing Back does not crash. When the fragment is popped, onDestroy() runs right after onDestroyView(), before the callback can reach the main thread, and the same holds for rotation and for closing the settings. The callback only meets a null binding if the fragment stays alive without its view, for example on the back stack, and no navigation from this screen does that today. So this closes a latent crash, not one users can hit right now.

Fixes the following issue(s)

Testing/QA

Devices
  • Samsung Galaxy S24 (SM-S921B), Android 16, debug builds of dev and of this branch: added an unreachable instance (10.255.255.1) and pressed Back right away, then waited for the request to time out. Neither build crashed; the request is disposed when the screen is left. Adding video.blender.org works with this change.
Steps for testing
  • I checked the lifecycle with a throwaway Robolectric test (not included, as NewPipe has no Robolectric setup). It opens the fragment, calls addInstance(), does one of five things and then lets the request finish. On dev, only "fragment kept on the back stack without its view" ends in NullPointerException: Cannot read field "loadingProgressBar" because "this.binding" is null. Back, rotation, closing the settings and the open screen are fine. With this change none of the five fails. Happy to share the test if useful.
  • ./gradlew :app:testDebugUnitTest and :app:assembleDebug pass.
APK for testing

The APK can be found by going to the "Checks" tab below the title. On the left pane, click on "CI", scroll down to "artifacts" and click "app" to download the zip file which contains the debug APK of this PR. You can find more info and a video demonstration on this wiki page.

Due diligence

Disclaimer: Found the issue by test-driving an LM-powered vulnerability scanner I work on heavily. The fix and this description were drafted with AI help and reviewed by me.

addInstance() hides binding.loadingProgressBar once the instance request
finishes, but the request was only disposed in onDestroy(), while
onDestroyView() already sets binding to null. Leaving the screen is fine
today, because onDestroy() runs right after onDestroyView(). If the
fragment ever stays alive without its view, for example on the back
stack, the callback dereferences the null binding.

Clear the disposables in onDestroyView() so the request ends together
with the view it updates.

Fixes TeamNewPipe#13871

Reported-by: BS.ehlas.cz
@sonarqubecloud

Copy link
Copy Markdown

@theimpulson

Copy link
Copy Markdown
Member

@Huge thanks for the PR. Could you agree with the AI policy and also test your change on a real device to verify if your issue is fixed?

@Huge

Huge commented Oct 18, 2026

Copy link
Copy Markdown
Author

Tested on a Samsung Galaxy S24 (Android 16) with debug builds of dev and of this branch. I added an unreachable instance (10.255.255.1), pressed Back right away and waited for the request to time out. Neither build crashed; in both the request is disposed when the screen is left, as described above. Adding a real instance (video.blender.org) still works with this change. The case this PR guards against, the fragment staying alive without its view, can't be reached from the UI right now, so it is only covered by the Robolectric check from the description.

@ShareASmile ShareASmile added the bug Issue is related to a bug label Oct 19, 2026
@Huge

Huge commented Oct 27, 2026

Copy link
Copy Markdown
Author

Friendly ping: is there anything else you need from me to get this merged? Happy to adjust.

theimpulson
theimpulson previously approved these changes Oct 27, 2026
@Override
public void onDestroy() {
super.onDestroy();
if (disposables != null) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick but this can be probably removed and the check could be added to the onDestoryView call

@theimpulson

Copy link
Copy Markdown
Member

Friendly ping: is there anything else you need from me to get this merged? Happy to adjust.

Thanks, looks good to me other than one minor comment to avoid duplicate calls.

@theimpulson
theimpulson dismissed their stale review October 27, 2026 11:03

No NPE on dev neither does this seems to fix log message

@theimpulson

Copy link
Copy Markdown
Member

@Huge some questions.

So this closes a latent crash, not one users can hit right now.

Does this means that your issue actually was reported without testing/reproduction? If not, how did you document it as NPE with log message? Asking as I am unable to see any changes of this PR.

Second question from me is, did you use any AI to report or generate this fix? If so, how much of the involvement was done with AI in both issue reporting and this MR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Issue is related to a bug size/small PRs with less than 50 changed lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

NullPointerException in PeertubeInstanceListFragment.addInstance() due to Rx callback after onDestroyView()

3 participants