Skip to content

Do not assert a namespace separator when reporting a missing mapping file - #522

Closed
dchaudhari7177 wants to merge 1 commit into
doctrine:3.4.xfrom
dchaudhari7177:fix/520-root-namespace-mapping-file
Closed

dchaudhari7177 wants to merge 1 commit into
doctrine:3.4.xfrom
dchaudhari7177:fix/520-root-namespace-mapping-file

Conversation

@dchaudhari7177

Copy link
Copy Markdown

Fixes #520. Targets 3.4.x, since the assertion is on every maintained branch (3.4.x, 4.2.x, 4.3.x, 5.0.x) and merges up.

@derrabus's reading in the issue is right: $pos exists only to render the exception message, so there is nothing there to assert.

$pos = strrpos($className, '\');
assert(is_int($pos));

throw MappingException::mappingFileNotFound(
    $className,
    substr($className, $pos + 1) . $this->fileExtension
);

A class in the root namespace has no separator, strrpos() returns false, and with zend.assertions on the caller gets an AssertionError from the line that was trying to build a MappingException. So the failure replaces the error you were meant to see with a different one, from one line above it.

The special case is that such a class is its own short name — DateTime is DateTime — which is a perfectly good thing to name in the message:

($pos === false ? $className : substr($className, $pos + 1)) . $this->fileExtension

use function assert; and use function is_int; go with it; they were only there for that line, and phpcs flags them otherwise.

Verified

Red before green, with the production file stashed and the new test left in place:

$ php -d zend.assertions=1 vendor/bin/phpunit --filter FindMappingFileNotFoundForClassInRootNamespace
1) …SymfonyFileLocatorTest::testFindMappingFileNotFoundForClassInRootNamespace
Failed asserting that exception of type "AssertionError" matches expected exception
"Doctrine\Persistence\Mapping\MappingException".
Message was: "assert(is_int($pos))" at src/Mapping/Driver/SymfonyFileLocator.php:247

That is the reported bug reproduced exactly. With the fix:

$ php -d zend.assertions=1 vendor/bin/phpunit
OK (138 tests, 262 assertions)

$ vendor/bin/phpcs
$ vendor/bin/phpstan analyse --memory-limit=1G
 [OK] No errors

The new test asserts the message the caller should have been getting all along:

No mapping file found named 'DateTime.yml' for class 'DateTime'.

Note

The reproduction in the issue reaches findMappingFile() for DateTime in the first place, which is arguably its own question — but that path throws MappingException for every other class name, and it should for this one too rather than dying one line earlier with a different error class.

…file

SymfonyFileLocator::findMappingFile() ends by computing the class's short
name for the exception message:

    $pos = strrpos($className, '\');
    assert(is_int($pos));

A class in the root namespace has no separator, so strrpos() returns false and
the assertion fails. With zend.assertions enabled the caller gets an
AssertionError instead of the MappingException the method is trying to throw:

    $locator = new SymfonyFileLocator([]);
    $locator->findMappingFile(DateTime::class);

The realistic route in is AbstractQuery::setParameter() with a DateTime value
and no explicit type.

$pos exists only to render the message, so there is nothing to assert. A class
with no separator is its own short name, which is a perfectly good thing to
put in the message.
@greg0ire greg0ire added the Bug Something isn't working label Sep 10, 2026
@greg0ire

Copy link
Copy Markdown
Member

Hang on… this is a duplicate of #521

@GromNaN

GromNaN commented Sep 11, 2026

Copy link
Copy Markdown
Member

Closing as duplicate.

@GromNaN GromNaN closed this Sep 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants