Repository navigation
Route the remaining ResultSet and Container throw sites through named constructors - #195
Merged
simon-mundy merged 2 commits intoSep 29, 2026
Conversation
6 tasks
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
simon-mundy
force-pushed
the
exception/pr-6-resultset-container
branch
from
September 28, 2026 22:52
2f46c04 to
0eceb96
Compare
… constructors The last 5 throw sites outside the components covered by php-db#191 to php-db#194. Message text is byte-identical, verified template by template against the originals. - Add ResultSet\Exception\RuntimeException::forUnbufferedIteration() - Add forNonAdapterAwareDelegate() to Exception\ContainerException, and give the three reasons that AdapterInterfaceFactory and AbstractAdapterInterfaceFactory passed as inline strings their own factories: forMissingConfigService(), forMissingConfiguration() and forMissingDriver(), each composing the reason into the SERVICE template - Retype the delegator's non-AdapterAware guard from the root Exception\RuntimeException to ContainerException, which extends it, so the failure carries PSR-11's ContainerExceptionInterface as a container failure should - Own the "not found in container" wording as ContainerException::MISSING_SERVICE while still throwing the ServiceManager's own ServiceNotFoundException. Laminas annotates that class @Final, so this package cannot own it; the throw site renders the template itself, which docs/book/exceptions.md now records as the single documented exception to the convention - Derive the message assertions in the six test files the earlier PRs do not touch from the templates rather than restating them One literal assertion is deliberately left in test/unit/Container/TableIdentifierFactoryFactoryTest.php: it asserts Sql\Exception\InvalidArgumentException::EMPTY_SEPARATOR, a constant php-db#192 introduces, so it can only be migrated once that has landed. Signed-off-by: Simon Mundy <simon.mundy@peptolab.com>
simon-mundy
force-pushed
the
exception/pr-6-resultset-container
branch
from
September 29, 2026 03:35
0eceb96 to
de32800
Compare
tyrsson
approved these changes
Sep 29, 2026
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.
Types of changes
Checklist:
Description
PR 6 of 6 from #189, and the last: the throw sites outside the components #191 to #194 cover.
Message text is byte-identical, verified template by template against the original literals.
ResultSet\Exception\RuntimeException::forUnbufferedIteration().ContainerException::forNonAdapterAwareDelegate(), plus factories for the three reasons thatAdapterInterfaceFactoryandAbstractAdapterInterfaceFactorywere passing toforService()as inline strings:forMissingConfigService(),forMissingConfiguration()andforMissingDriver(). Each composes the reason into theSERVICEtemplate, so the composed messages are verified as well as the templates.AdapterAwareguard is retyped from the rootException\RuntimeExceptiontoContainerException, which extends it. A container failure should carry PSR-11'sContainerExceptionInterface, and nothing catching the old type is affected.One documented exception to the convention
The delegator's "not found in container" guard must throw the ServiceManager's own
ServiceNotFoundException— the container contract decides the type. I first extended that class so the template could live on it, andmago analyzecorrectly refused: Laminas annotates it@final. It is notfinalin PHP today, so runtime reflection and the test suite both accepted the subclass, but the annotation is a clear statement of intent and extending it would break when Laminas enforces it.So this package owns the wording without owning the class: the template is
ContainerException::MISSING_SERVICEand that one throw site renders it itself.docs/book/exceptions.mdrecords it as the single place the convention does not apply, and why. Everywhere the thrown type is ours, the rule holds without exception.Motivation and Context
Refs #189. Depends on #190.
Scope is deliberately limited to what the other PRs do not touch, so this does not conflict with them:
ResultSet,ContainerandAdapter/Container. One literal assertion is left intest/unit/Container/TableIdentifierFactoryFactoryTest.phpbecause it assertsSql\Exception\InvalidArgumentException::EMPTY_SEPARATOR, a constant #192 introduces — it can be migrated in a follow-up once that lands.With #191 to #194, this completes the conversion: no
throw newremains anywhere insrc/.How has this been tested?
mago format --check,mago lintandmago analyzeall exit 0. Full unit suite passes: 1630 tests, 3529 assertions.Patch coverage measured locally at 16/16 lines, computed the way
codecov/patchdoes, before pushing. #194 failed that check on a method whose test class had never declared it in#[CoversMethod], so coverage was executed but not attributed; this PR was checked against that trap up front.