Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 51f3788

Browse files
committed
[AssetMapper] Fixing bug where a circular exception could be thrown while making error message
1 parent 8a93c4c commit 51f3788

File tree

4 files changed

+54
-3
lines changed

4 files changed

+54
-3
lines changed

src/Symfony/Component/AssetMapper/Compiler/JavaScriptImportPathCompiler.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Psr\Log\NullLogger;
1616
use Symfony\Component\AssetMapper\AssetDependency;
1717
use Symfony\Component\AssetMapper\AssetMapperInterface;
18+
use Symfony\Component\AssetMapper\Exception\CircularAssetsException;
1819
use Symfony\Component\AssetMapper\Exception\RuntimeException;
1920
use Symfony\Component\AssetMapper\MappedAsset;
2021

@@ -57,8 +58,12 @@ public function compile(string $content, MappedAsset $asset, AssetMapperInterfac
5758
if (!$dependentAsset) {
5859
$message = sprintf('Unable to find asset "%s" imported from "%s".', $matches[1], $asset->sourcePath);
5960

60-
if (null !== $assetMapper->getAsset(sprintf('%s.js', $resolvedPath))) {
61-
$message .= sprintf(' Try adding ".js" to the end of the import - i.e. "%s.js".', $matches[1]);
61+
try {
62+
if (null !== $assetMapper->getAsset(sprintf('%s.js', $resolvedPath))) {
63+
$message .= sprintf(' Try adding ".js" to the end of the import - i.e. "%s.js".', $matches[1]);
64+
}
65+
} catch (CircularAssetsException $e) {
66+
// avoid circular error if there is self-referencing import comments
6267
}
6368

6469
$this->handleMissingImport($message);
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\AssetMapper\Exception;
13+
14+
/**
15+
* Thrown when a circular reference is detected while creating an asset.
16+
*/
17+
class CircularAssetsException extends RuntimeException
18+
{
19+
}

src/Symfony/Component/AssetMapper/Factory/MappedAssetFactory.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\AssetMapper\Factory;
1313

1414
use Symfony\Component\AssetMapper\AssetMapperCompiler;
15+
use Symfony\Component\AssetMapper\Exception\CircularAssetsException;
1516
use Symfony\Component\AssetMapper\Exception\RuntimeException;
1617
use Symfony\Component\AssetMapper\MappedAsset;
1718
use Symfony\Component\AssetMapper\Path\PublicAssetsPathResolverInterface;
@@ -36,7 +37,7 @@ public function __construct(
3637
public function createMappedAsset(string $logicalPath, string $sourcePath): ?MappedAsset
3738
{
3839
if (\in_array($logicalPath, $this->assetsBeingCreated, true)) {
39-
throw new RuntimeException(sprintf('Circular reference detected while creating asset for "%s": "%s".', $logicalPath, implode(' -> ', $this->assetsBeingCreated).' -> '.$logicalPath));
40+
throw new CircularAssetsException(sprintf('Circular reference detected while creating asset for "%s": "%s".', $logicalPath, implode(' -> ', $this->assetsBeingCreated).' -> '.$logicalPath));
4041
}
4142

4243
if (!isset($this->assetsCache[$logicalPath])) {

src/Symfony/Component/AssetMapper/Tests/Compiler/JavaScriptImportPathCompilerTest.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Symfony\Component\AssetMapper\AssetMapperInterface;
1717
use Symfony\Component\AssetMapper\Compiler\AssetCompilerInterface;
1818
use Symfony\Component\AssetMapper\Compiler\JavaScriptImportPathCompiler;
19+
use Symfony\Component\AssetMapper\Exception\CircularAssetsException;
1920
use Symfony\Component\AssetMapper\Exception\RuntimeException;
2021
use Symfony\Component\AssetMapper\MappedAsset;
2122

@@ -277,6 +278,31 @@ public static function provideMissingImportModeTests(): iterable
277278
];
278279
}
279280

281+
public function testErrorMessageAvoidsCircularException()
282+
{
283+
$assetMapper = $this->createMock(AssetMapperInterface::class);
284+
$assetMapper->expects($this->any())
285+
->method('getAsset')
286+
->willReturnCallback(function ($logicalPath) {
287+
if ($logicalPath === 'htmx') {
288+
return null;
289+
}
290+
291+
if ($logicalPath === 'htmx.js') {
292+
throw new CircularAssetsException();
293+
}
294+
});
295+
296+
$asset = new MappedAsset('html.js', '/path/to/app.js');
297+
$compiler = new JavaScriptImportPathCompiler();
298+
$content = '//** @type {import("./htmx").HtmxApi} */';
299+
$compiled = $compiler->compile($content, $asset, $assetMapper);
300+
// To form a good exception message, the compiler will check for the
301+
// htmx.js asset, which will throw a CircularAssetsException. This
302+
// should not be caught.
303+
$this->assertSame($content, $compiled);
304+
}
305+
280306
private function createAssetMapper(): AssetMapperInterface
281307
{
282308
$assetMapper = $this->createMock(AssetMapperInterface::class);

0 commit comments

Comments
 (0)