Still finishing the rest of my review but I did find a blocker so posting it now.
On Linux, if the saved GUI-selected custom datadir still exists but is no longer readable, the app aborts at launch with an unhandled exception instead of re-showing the datadir chooser:
terminate called after throwing an instance of 'std::filesystem::__cxx11::filesystem_error'
what(): filesystem error: status: Permission denied [/bitcoin.conf]
Aborted (core dumped)
Repro:
- Fresh config dir, onboard choosing a custom data directory.
- chmod 000 (or any state where the directory exists but cannot be traversed, for example an external drive that remounts root-owned).
- Relaunch. Expected: the storage location chooser reappears. Actual: abort before any window, on every launch, until the user fixes permissions by hand or passes -choosedatadir.
Root cause: ResolveOnboardingStartupStatus correctly computes force_show_onboarding (ShouldShowDataDirChooser flags the directory as not writable), but then still reads the profile from it, because the gate is custom_datadir_exists = QFileInfo::exists(...) (qml/onboarding_settings.cpp, around line 406), and a mode-000 directory exists. It applies the datadir to the preview args and calls ReadConfigFiles, where fs::is_directory(conf_path) (src/common/config.cpp:134) stats /bitcoin.conf, gets EACCES, and throws. Nothing on the QML startup path catches std::filesystem_error, so the process terminates.
Suggested fix, two parts:
- Gate the profile read on the datadir being usable, not merely existing: the ValidateCustomDataDir result is already computed for force_show_onboarding two lines above, so can_read_profile should exclude a custom datadir that failed validation.
- Wrap the preview's config/settings read in a try/catch that turns fs::filesystem_error into status.error, so any remaining gap of this kind degrades to the onboarding error path instead of std::terminate.
The existing unit test covers the unwritable case (guiDataDirChooserShowsForUnwritableConfiguredDir) but not the unreadable one, which is why this survives a green suite; a sibling test with a mode-000 directory would pin the fix.
Originally posted by @epicleafies in #742 (comment)
Still finishing the rest of my review but I did find a blocker so posting it now.
On Linux, if the saved GUI-selected custom datadir still exists but is no longer readable, the app aborts at launch with an unhandled exception instead of re-showing the datadir chooser:
terminate called after throwing an instance of 'std::filesystem::__cxx11::filesystem_error'
what(): filesystem error: status: Permission denied [/bitcoin.conf]
Aborted (core dumped)
Repro:
Root cause: ResolveOnboardingStartupStatus correctly computes force_show_onboarding (ShouldShowDataDirChooser flags the directory as not writable), but then still reads the profile from it, because the gate is custom_datadir_exists = QFileInfo::exists(...) (qml/onboarding_settings.cpp, around line 406), and a mode-000 directory exists. It applies the datadir to the preview args and calls ReadConfigFiles, where fs::is_directory(conf_path) (src/common/config.cpp:134) stats /bitcoin.conf, gets EACCES, and throws. Nothing on the QML startup path catches std::filesystem_error, so the process terminates.
Suggested fix, two parts:
The existing unit test covers the unwritable case (guiDataDirChooserShowsForUnwritableConfiguredDir) but not the unreadable one, which is why this survives a green suite; a sibling test with a mode-000 directory would pin the fix.
Originally posted by @epicleafies in #742 (comment)