diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 7a9cb87ec89..3a3f3fc2eb5 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -13,6 +13,7 @@ This serves two purposes: - You can now specify navigation priorities by adding a numeric prefix to the source file names in https://github.com/hydephp/develop/pull/1709 - Added a new `\Hyde\Framework\Actions\PreBuildTasks\TransferMediaAssets` build task handle media assets transfers for site builds. - Added a new `\Hyde\Framework\Exceptions\ParseException` exception class to handle parsing exceptions in data collection files in https://github.com/hydephp/develop/pull/1732 +- Added a new `\Hyde\Framework\Exceptions\InvalidConfigurationException` exception class to handle invalid configuration exceptions in https://github.com/hydephp/develop/pull/1799 - The `\Hyde\Facades\Features` class is no longer marked as internal, and is now thus part of the public API. ### Changed diff --git a/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php b/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php new file mode 100644 index 00000000000..67a13ba331c --- /dev/null +++ b/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php @@ -0,0 +1,47 @@ +file, $this->line] = $this->findConfigLine($namespace, $key); + } + + parent::__construct($message); + } + + /** + * @experimental Please report any issues with this method to the authors at https://github.com/hydephp/develop/issues + * + * @return array{string, int} + */ + protected function findConfigLine(string $namespace, string $key): array + { + $file = realpath("config/$namespace.php"); + $contents = Filesystem::getContents($file); + $lines = explode("\n", $contents); + + foreach ($lines as $line => $content) { + if (str_contains($content, "'$key' =>")) { + break; + } + } + + assert($file !== false); + assert(isset($line)); + + return [$file, $line + 1]; + } +} diff --git a/packages/framework/tests/Unit/CustomExceptionsTest.php b/packages/framework/tests/Unit/CustomExceptionsTest.php index 38be357f085..dc6e9b460f7 100644 --- a/packages/framework/tests/Unit/CustomExceptionsTest.php +++ b/packages/framework/tests/Unit/CustomExceptionsTest.php @@ -13,12 +13,14 @@ use Hyde\Framework\Exceptions\ParseException; use RuntimeException; use Exception; +use Hyde\Framework\Exceptions\InvalidConfigurationException; /** * @covers \Hyde\Framework\Exceptions\FileConflictException * @covers \Hyde\Framework\Exceptions\FileNotFoundException * @covers \Hyde\Framework\Exceptions\RouteNotFoundException * @covers \Hyde\Framework\Exceptions\UnsupportedPageTypeException + * @covers \Hyde\Framework\Exceptions\InvalidConfigurationException * @covers \Hyde\Framework\Exceptions\ParseException */ class CustomExceptionsTest extends UnitTestCase @@ -173,4 +175,30 @@ public function testParseExceptionWithPrevious() $this->assertSame("Invalid Markdown in file: 'example.md' (Parsing error)", $exception->getMessage()); $this->assertSame($previous, $exception->getPrevious()); } + + public function testInvalidConfigurationExceptionWithDefaultMessage() + { + $exception = new InvalidConfigurationException(); + + $this->assertSame('Invalid configuration detected.', $exception->getMessage()); + } + + public function testInvalidConfigurationExceptionWithCustomMessage() + { + $exception = new InvalidConfigurationException('Custom error message.'); + + $this->assertSame('Custom error message.', $exception->getMessage()); + } + + public function testInvalidConfigurationExceptionWithNamespaceAndKey() + { + $exception = new InvalidConfigurationException('Invalid configuration.', 'hyde', 'name'); + + $this->assertSame('Invalid configuration.', $exception->getMessage()); + $this->assertFileExists($exception->getFile()); + $this->assertIsInt($exception->getLine()); + + $this->assertStringContainsString('config'.DIRECTORY_SEPARATOR.'hyde.php', $exception->getFile()); + $this->assertGreaterThan(0, $exception->getLine()); + } }