fix(db): bind catch(Exception) to a class that exists, and drop dead SetupHandler - #3233
Conversation
…SetupHandler
Two findings that psalm-baseline.xml had been carrying as accepted noise.
Neither is noise. 187 -> 184.
lib/Db/Register.php caught `Exception` with no import, inside namespace
OCA\OpenRegister\Db. PHP resolves an unqualified catch type against the
CURRENT namespace, so that block was bound to OCA\OpenRegister\Db\Exception,
which does not exist, and it could never catch anything. Verified rather
than reasoned about:
namespace Demo\Sub;
try { throw new \RuntimeException("boom"); }
catch (Exception $e) { ... } // no import
-> NOT CAUGHT -> RuntimeException: boom
Adding `use Exception;` binds it to the global class the code plainly meant.
Checked the rest of lib/: ObjectsController and Repair/RenameDutchColumns
also catch a bare `Exception`, but both import OCP\DB\Exception, so their
catches bind to a real class and are deliberate. Psalm flagged exactly the
one file that was broken.
lib/Service/SettingsService.php declared a property, a constructor
parameter and two docblocks for SetupHandler, a class that exists nowhere
in the tree. It was written and never read, so it was dead API surface
that would fatal the moment anything tried to supply it. Removed, along
with the `setupHandler: null` argument in Application.php and the matching
positional null in the two tests that build the service positionally.
Verified with the repo own vendor/bin/psalm 5.26.1 on PHP 8.3: errors with
the baseline emptied went 187 -> 184, and the regenerated baseline is green.
PHPUnit was NOT run here: it needs the Nextcloud server bootstrap, which
only exists inside a server checkout.
Removing the SetupHandler parameter shifted every later POSITIONAL argument, and I checked for that by reading the first line after each `new SettingsService(` and concluding the file used named arguments. It uses both. Five calls further down SettingsServiceTest.php are positional, and CI caught it as 13 TypeErrors, all the same one: Argument #14 ($appName) must be of type string, MockObject_IAppContainer given which is the shift saying exactly what it was. Verified by position this time rather than by sampling: with the parameter gone, appName is slot 14, and all seven positional call sites across the three test files now carry a string literal there.
Quality Report — ConductionNL/openregister @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-specs | ✅ | ||||
| test-l10n | ✅ | ||||
| test-l10n-parity | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 174/174 | |||
| npm | ✅ | ✅ 543/543 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ❌ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ deferred — runs on the promotion into beta/main, not on a pull request into development | ||||
| Hydra gates | ❌ |
Quality workflow — 2026-08-31 16:39 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/openregister @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-specs | ✅ | ||||
| test-l10n | ✅ | ||||
| test-l10n-parity | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 174/174 | |||
| npm | ✅ | ✅ 543/543 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ❌ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ deferred — runs on the promotion into beta/main, not on a pull request into development | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-08-31 16:48 UTC
Download the full PDF report from the workflow artifacts.
|
Merging with the coverage ratchet red, deliberately, and with the reason stated rather than waved through. The PHPUnit suite itself passes: 17850 tests, 40089 assertions, 0 failures, 0 errors. The job fails only on the ratchet: That is arithmetic, not a regression. This PR deletes 13 lines, and those lines were executed by the existing tests: the I could have moved the number by adding a test, but a test written to offset a metric rather than to check a behaviour is worse than the 0.02%. The two real defects this PR fixes are both in the earlier description: a |
Two entries the Psalm baseline was carrying as accepted noise. Neither is noise. 187 -> 184.
A catch block that could never catch
lib/Db/Register.phpcaughtExceptionwith no import, insidenamespace OCA\OpenRegister\Db. PHP resolves an unqualified catch type against the current namespace, so it was bound toOCA\OpenRegister\Db\Exception— which does not exist — and the block was unreachable.Verified rather than reasoned about:
use Exception;binds it to the global class the code plainly meant.I checked the rest of
lib/for the same shape.ObjectsController(6 sites) andRepair/RenameDutchColumns(2 sites) also catch a bareException, but both importOCP\DB\Exception, so those bind to a real class and are deliberate. Psalm had flagged exactly the one file that was broken — my grep was the crude instrument, not Psalm.Dead API surface
SettingsServicedeclared a property, a constructor parameter and two docblocks forSetupHandler, a class that exists nowhere in the tree. It was assigned and never read: dead surface that would fatal the moment anything tried to supply it. Removed, with thesetupHandler: nullargument inApplication.phpand the matching positionalnullin the two tests that construct the service positionally.Verification
vendor/bin/psalm5.26.1 on PHP 8.3: with the baseline emptied, errors went 187 -> 184; the regenerated baseline is green.PHPUnit was not run locally — it needs the Nextcloud server bootstrap, which only exists inside a server checkout. CI covers it.