Skip to content

fix(archival): call a mapper method that exists, and correct a @throws - #3239

Merged
rubenvdlinde merged 2 commits into
developmentfrom
fix/archival-calls-a-mapper-method-that-does-not-exist
Aug 31, 2026
Merged

fix(archival): call a mapper method that exists, and correct a @throws#3239
rubenvdlinde merged 2 commits into
developmentfrom
fix/archival-calls-a-mapper-method-that-does-not-exist

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

Six calls to MagicMapper::findByUuid() — a method MagicMapper does not have.

Fourteen other mappers define findByUuid, which is exactly what makes the call look correct at a glance. 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);

wrapped 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 returns ObjectEntity, and it throws DoesNotExistException when absent — which is precisely what these call sites expect and already 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.

Verification

vendor/bin/psalm 5.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).

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.
@github-actions

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/openregister @ 0f040db

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.
@github-actions

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/openregister @ 8066cb9

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.

@rubenvdlinde
rubenvdlinde merged commit f26b368 into development Aug 31, 2026
47 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant