fix(archival): call a mapper method that exists, and correct a @throws - #3239
Merged
rubenvdlinde merged 2 commits intoAug 31, 2026
Merged
Conversation
Six calls to MagicMapper::findByUuid(), a method MagicMapper does not have.
Fourteen OTHER mappers define findByUuid, which is what makes the call look
right, but MagicMapper is not one of them, AbstractObjectMapper only
declares abstract find/findAll/findMultiple/findBySchema, and neither has
__call or a trait supplying it.
The failure mode is worse than a 404. `Call to undefined method` raises a
PHP Error, and Error does NOT extend Exception, so the
} catch (\Exception $e) {
return new JSONResponse(["error" => "... not found"], 404);
around every one of these never catches it. Five archival endpoints and one
destruction path answer with an uncaught fatal instead of the 404 they were
written to return.
MagicMapper::find(string|int $identifier, ...) is the method meant here: its
own docblock says the identifier may be an "ID, UUID, slug, or URI", it
returns ObjectEntity, and it throws DoesNotExistException when the object is
absent, which is exactly what these call sites expect and catch.
Also corrected a @throws in ObjectService::rejectIfTransferred that named
\OCP\AppFramework\Http\ContentSecurityPolicy, a CSP class rather than an
exception. The method throws DoesNotExistException.
Verified with the repo own vendor/bin/psalm 5.26.1 on PHP 8.3: errors with
the baseline emptied went 180 -> 173, regenerated baseline is green. PHPUnit
was NOT run here, it needs the Nextcloud server bootstrap that only exists
inside a server checkout.
Contributor
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 17:27 UTC
Download the full PDF report from the workflow artifacts.
The four archival test files all did:
->addMethods([\x27findByUuid\x27])
addMethods() is PHPUnit\x27s API for mocking a method the class DOES NOT
HAVE. That is why this bug lived: the tests had to invent findByUuid on
MagicMapper to stub it, so the suite was green while production raised
`Call to undefined method` on every archival endpoint. The mock documented
the defect and nobody read it that way.
ArchivalControllerTest and DestructionServiceTest now stub the real method
with onlyMethods([..., \x27find\x27]), and their 14 ->method(\x27findByUuid\x27)
expectations point at find().
LegalHoldServiceTest and DestructionCertificateContentTest never called it
at all: their addMethods was dead invention, so it is simply removed.
🔑 onlyMethods() fails loudly when the method does not exist. addMethods()
cannot, by design. Prefer onlyMethods for anything that is supposed to be
real.
Contributor
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 17:38 UTC
Download the full PDF report from the workflow artifacts.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Six calls to
MagicMapper::findByUuid()— a methodMagicMapperdoes not have.Fourteen other mappers define
findByUuid, which is exactly what makes the call look correct at a glance.MagicMapperis not one of them;AbstractObjectMapperonly declares abstractfind/findAll/findMultiple/findBySchema; and neither has__callor a trait supplying it.The failure mode is worse than a 404
Call to undefined methodraises a PHPError, andErrordoes not extendException. So thewrapped around every one of these never catches it. Five archival endpoints and one destruction path answer with an uncaught fatal instead of the 404 they were written to return.
The fix
MagicMapper::find(string|int $identifier, ...)is the method meant here. Its own docblock says the identifier may be an "ID, UUID, slug, or URI", it returnsObjectEntity, and it throwsDoesNotExistExceptionwhen absent — which is precisely what these call sites expect and already catch.Also corrected a
@throwsinObjectService::rejectIfTransferredthat named\OCP\AppFramework\Http\ContentSecurityPolicy, a CSP class rather than an exception. The method throwsDoesNotExistException.Verification
vendor/bin/psalm5.26.1 on PHP 8.3: errors with the baseline emptied went 180 -> 173, regenerated baseline green. PHPUnit not run locally (needs the server bootstrap).