Skip to content

Conversation

@Kartikey15dem
Copy link

@Kartikey15dem Kartikey15dem commented Dec 16, 2025

Fixes - #19553

ManageSpaceActivity crashes on startup when getExternalFilesDir() unexpectedly
returns null.

Solution

  • Handle the fatal storage exception early inside IntentHandler.getAllStoragePermissions: detect the null storage directory, show a fatal error dialog, and ensure the originating activity finishes after user acknowledgement.
  • Keep a secondary fallback in MainActivity to catch any uncaught fatal storage exception and present the same fatal dialog as a last resort.
  • Send a silent crash report when an unexpected action or fatal storage condition occurs.

Tests

  • Add a Robolectric test that simulates getExternalFilesDir() returning null when invoked by IntentHandler.getAllStoragePermissions. Verify the fatal error dialog is shown and the activity finishes after dismissal.
  • Retain assertions that crash reports are sent when appropriate.

Notes

-Keeps error handling as close to the permission/intent flow as possible, improving UX and limiting the need for global fallbacks.

Copilot AI review requested due to automatic review settings December 16, 2025 16:03
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes a crash in ManageSpaceActivity when getExternalFilesDir() returns null despite external storage being mounted. The fix catches the fatal storage exception during activity startup and displays an error dialog instead of crashing.

  • Added error handling in onCreate() to catch and handle storage-related RuntimeExceptions
  • Implemented a fatal error dialog that finishes the activity after user acknowledgement
  • Added comprehensive Robolectric tests to verify the error handling behavior

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
ManageSpaceActivity.kt Added error handling in onCreate to catch storage exceptions and display fatal error dialog
ManageSpaceActivityNoExternalFilesDirTest.kt Added test coverage for null getExternalFilesDir scenario and dialog behavior

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@david-allison david-allison marked this pull request as draft December 16, 2025 16:45
@Kartikey15dem Kartikey15dem marked this pull request as ready for review December 17, 2025 04:37
override fun onCreate(savedInstanceState: Bundle?) {
try {
super.onCreate(savedInstanceState)
} catch (e: RuntimeException) {
Copy link
Member

Choose a reason for hiding this comment

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

Why?

Copy link
Author

Choose a reason for hiding this comment

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

Why?

The exception is being thrown during the creation of the ManageSpaceActivity and if its not throwing an exception then I think the super.onCreate needs to be called if the onCreate function is being overriden. So either the exception needs to be handled in ManageSpaceActivity or somewhere before where it actually occurs and being thrown but that would need to handle it at multiple places . So if you suggest any better way to handle it I will surely implement it.

Copy link
Member

Choose a reason for hiding this comment

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

@sanjaysargam This exception comes from:

if (!ensureStoragePermissions()) {
return
}

Could you take a look through the logic?

Copy link
Member

Choose a reason for hiding this comment

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

Ok

Copy link
Member

Choose a reason for hiding this comment

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

the exception happens in ensureStoragePermissions() before ManageSpaceActivity.onCreate() is reached.
So the crash happens earlier in the call chain, and our try-catch in ManageSpaceActivity never runs.
I think the best fix is to catch SystemStorageException in IntentHandler.grantedStoragePermissions() and treat it as "permission not granted" so the activity finishes cleanly instead of crashing.
We can keep the ManageSpaceActivity fix as a safety net, but handling it in IntentHandler feels like the right primary fix.

@david-allison
Copy link
Member

If you're going to put an AI reviewer on the PR, don't leave the comments unhandled.

The code style is unusual - why would you catch super.onCreate?

@david-allison david-allison marked this pull request as draft December 18, 2025 08:32
@david-allison david-allison added the Needs Author Reply Waiting for a reply from the original author label Dec 18, 2025
@Kartikey15dem Kartikey15dem marked this pull request as ready for review December 18, 2025 09:43
@Kartikey15dem
Copy link
Author

Kartikey15dem commented Dec 19, 2025

The exception is being thrown during the creation of the ManageSpaceActivity and if its not throwing an exception then I think the super.onCreate needs to be called if the onCreate function is being overriden. So either the exception needs to be handled in ManageSpaceActivity or somewhere before where it actually occurs and being thrown but that would need to handle it at multiple places . So if you suggest any better way to handle it I will surely implement it.

@david-allison david-allison added Needs reviewer reply Waiting for a reply from another reviewer and removed Needs Author Reply Waiting for a reply from the original author labels Dec 20, 2025
@sanjaysargam
Copy link
Member

Could you please add How has been tested in PR description.
or else share reproduction steps to test


private fun isFatalStorageError(e: Throwable): Boolean =
e.message?.contains(
"getExternalFilesDir unexpectedly returned null",
Copy link
Member

Choose a reason for hiding this comment

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

This string might change across Android versions. I'd suggest you to use a more robust detection method

private fun showFatalErrorDialog(e: Throwable) {
AlertDialog
.Builder(this)
.setTitle("Fatal error")
Copy link
Member

Choose a reason for hiding this comment

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

It should be localized

override fun onCreate(savedInstanceState: Bundle?) {
try {
super.onCreate(savedInstanceState)
} catch (e: RuntimeException) {
Copy link
Member

Choose a reason for hiding this comment

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

the exception happens in ensureStoragePermissions() before ManageSpaceActivity.onCreate() is reached.
So the crash happens earlier in the call chain, and our try-catch in ManageSpaceActivity never runs.
I think the best fix is to catch SystemStorageException in IntentHandler.grantedStoragePermissions() and treat it as "permission not granted" so the activity finishes cleanly instead of crashing.
We can keep the ManageSpaceActivity fix as a safety net, but handling it in IntentHandler feels like the right primary fix.

@sanjaysargam sanjaysargam added Needs Author Reply Waiting for a reply from the original author and removed Needs reviewer reply Waiting for a reply from another reviewer labels Dec 21, 2025
@Kartikey15dem
Copy link
Author

Kartikey15dem commented Dec 21, 2025

@sanjaysargam
Did any of the dependencies got changed because I had reset my branch to the first commit which has passed all the Ci checks but then when I update my project then this import statement - import org.hamcrest.Matchers.instanceOf, is showing an error in the test files.

@sanjaysargam
Copy link
Member

Please squash your commits into one. If you need any help regarding this, let me know.

@Kartikey15dem
Copy link
Author

@sanjaysargam
Yes , sure it will of great help if you can brief me on that but still I am facing the issue which is being shown in the test files which I think is unrelated with my commits.

@sanjaysargam
Copy link
Member

@Kartikey15dem
git squash is simply use to combine multiple commits into one commit, so that it will be easy to read and reviewer can easily review the code.

  1. git rebase -i HEAD~N (here N is the last no.of commits you want to squash, in your case, it's 5), then you'll see last 5 commits
  2. keep the first commit as it is and change pick -> squash for rest of the commits
  3. write a clean meaningful commit message

@Kartikey15dem Kartikey15dem force-pushed the fix-managespace-null-external-files-dir branch 2 times, most recently from 929085f to 2d989ad Compare December 24, 2025 05:24
@Kartikey15dem
Copy link
Author

@sanjaysargam
All my checks have passed. Please merge the PR.

@sanjaysargam
Copy link
Member

just a small request. Tag only when it's really urgent. Maintainer review PR, when they are free.
Happy coding!

@Kartikey15dem
Copy link
Author

just a small request. Tag only when it's really urgent. Maintainer review PR, when they are free. Happy coding!

Oh really sorry, it was my first PR so I thought I have to notify the maintainer to get my PR merged. Will keep in mind next time.

@Haz3-jolt Haz3-jolt added Needs Review and removed Needs Author Reply Waiting for a reply from the original author labels Jan 4, 2026
@david-allison david-allison added the Needs Author Reply Waiting for a reply from the original author label Jan 5, 2026
@david-allison
Copy link
Member

We shouldn't have a try...catch around super.onCreate. This case should be handled properly

Storage exception handled inside intenthandler
@Kartikey15dem Kartikey15dem force-pushed the fix-managespace-null-external-files-dir branch from c7172fc to 78419fb Compare January 8, 2026 04:56
@Kartikey15dem
Copy link
Author

We shouldn't have a try...catch around super.onCreate. This case should be handled properly

I have removed it . I was just using it as a last resort but I think its unnecessary as I am I handling the exception where it is being thrown . All my checks have passed .

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

Labels

Needs Author Reply Waiting for a reply from the original author Needs Review New contributor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants