From bb566a650991705d293723eb05a25578d8200c70 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Sun, 7 Jul 2024 14:51:19 +0200 Subject: [PATCH 01/16] Create InvalidConfigurationException.php --- .../Exceptions/InvalidConfigurationException.php | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php diff --git a/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php b/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php new file mode 100644 index 00000000000..80c29c2d50e --- /dev/null +++ b/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php @@ -0,0 +1,10 @@ + Date: Sun, 7 Jul 2024 14:51:39 +0200 Subject: [PATCH 02/16] Update InvalidConfigurationException to extend InvalidArgumentException --- .../Framework/Exceptions/InvalidConfigurationException.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php b/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php index 80c29c2d50e..9394b39eb3d 100644 --- a/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php +++ b/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php @@ -4,7 +4,9 @@ namespace Hyde\Framework\Exceptions; -class InvalidConfigurationException +use InvalidArgumentException; + +class InvalidConfigurationException extends InvalidArgumentException { // } From 11dde57d1ed53158c4d26e13b2ff513f2f86c56d Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Sun, 7 Jul 2024 15:02:07 +0200 Subject: [PATCH 03/16] Override constructor --- .../Framework/Exceptions/InvalidConfigurationException.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php b/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php index 9394b39eb3d..ee57bc39266 100644 --- a/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php +++ b/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php @@ -8,5 +8,8 @@ class InvalidConfigurationException extends InvalidArgumentException { - // + public function __construct(string $message = 'Invalid configuration detected.') + { + parent::__construct($message); + } } From 5947a85ba314bd7c2402f649ba9690b3a9731312 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Sun, 7 Jul 2024 15:08:10 +0200 Subject: [PATCH 04/16] Create initial logic to find the errored config line --- .../InvalidConfigurationException.php | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php b/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php index ee57bc39266..b27f960bd70 100644 --- a/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php +++ b/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php @@ -8,8 +8,32 @@ class InvalidConfigurationException extends InvalidArgumentException { - public function __construct(string $message = 'Invalid configuration detected.') + public function __construct(string $message = 'Invalid configuration detected.', ?string $namespace = null, ?string $key = null) { + if ($namespace && $key) { + [$file, $line] = $this->findConfigLine($namespace, $key); + + if ($file && $line) { + $this->file = $file; + $this->line = $line; + } + } + parent::__construct($message); } + + protected function findConfigLine(string $namespace, string $key): array + { + $file = "config/$namespace.php"; + $contents = file_get_contents(base_path($file)); + $lines = explode("\n", $contents); + + foreach ($lines as $line => $content) { + if (str_contains($content, "'$key' =>")) { + break; + } + } + + return [$file, $line + 1]; + } } From 65d113c577b8d1189d5c0657c10ff7a406932e54 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Sun, 7 Jul 2024 15:08:45 +0200 Subject: [PATCH 05/16] Replace break with early return --- .../Framework/Exceptions/InvalidConfigurationException.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php b/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php index b27f960bd70..25589bffae9 100644 --- a/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php +++ b/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php @@ -30,10 +30,10 @@ protected function findConfigLine(string $namespace, string $key): array foreach ($lines as $line => $content) { if (str_contains($content, "'$key' =>")) { - break; + return [$file, $line + 1]; } } - return [$file, $line + 1]; + return [null, null]; } } From 0cf1c4d473d83f0395245ef2c99a9b2626b58e6a Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Sun, 7 Jul 2024 15:13:51 +0200 Subject: [PATCH 06/16] Add spacing --- .../src/Framework/Exceptions/InvalidConfigurationException.php | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php b/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php index 25589bffae9..771a368b7fb 100644 --- a/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php +++ b/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php @@ -26,6 +26,7 @@ protected function findConfigLine(string $namespace, string $key): array { $file = "config/$namespace.php"; $contents = file_get_contents(base_path($file)); + $lines = explode("\n", $contents); foreach ($lines as $line => $content) { From 4b751931ada809467324ad0192d93948c6327f38 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Sun, 7 Jul 2024 15:13:57 +0200 Subject: [PATCH 07/16] Annotate return types --- .../src/Framework/Exceptions/InvalidConfigurationException.php | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php b/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php index 771a368b7fb..d556429cc2b 100644 --- a/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php +++ b/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php @@ -22,6 +22,7 @@ public function __construct(string $message = 'Invalid configuration detected.', parent::__construct($message); } + /** @return array{string|null, int|null} */ protected function findConfigLine(string $namespace, string $key): array { $file = "config/$namespace.php"; From 52895b9f3884a20c2c7dbad62682532b8f308c72 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Sun, 7 Jul 2024 15:16:38 +0200 Subject: [PATCH 08/16] Remove graceful handling as internal developer needs to use proper paths If we can't find the line, it's probably because an internal/package developer made a mistake --- .../Exceptions/InvalidConfigurationException.php | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php b/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php index d556429cc2b..ef1b907e62c 100644 --- a/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php +++ b/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php @@ -13,10 +13,8 @@ public function __construct(string $message = 'Invalid configuration detected.', if ($namespace && $key) { [$file, $line] = $this->findConfigLine($namespace, $key); - if ($file && $line) { - $this->file = $file; - $this->line = $line; - } + $this->file = $file; + $this->line = $line; } parent::__construct($message); @@ -27,15 +25,14 @@ protected function findConfigLine(string $namespace, string $key): array { $file = "config/$namespace.php"; $contents = file_get_contents(base_path($file)); - $lines = explode("\n", $contents); foreach ($lines as $line => $content) { if (str_contains($content, "'$key' =>")) { - return [$file, $line + 1]; + break; } } - return [null, null]; + return [$file, $line + 1]; } } From 9d7cf76e5f02850d91158c1b0555472475ccb7dc Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Sun, 7 Jul 2024 15:21:37 +0200 Subject: [PATCH 09/16] Cleanup and improve the line finder code --- .../Exceptions/InvalidConfigurationException.php | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php b/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php index ef1b907e62c..8a6f7722492 100644 --- a/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php +++ b/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php @@ -4,8 +4,13 @@ namespace Hyde\Framework\Exceptions; +use Hyde\Facades\Filesystem; use InvalidArgumentException; +use function assert; +use function explode; +use function realpath; + class InvalidConfigurationException extends InvalidArgumentException { public function __construct(string $message = 'Invalid configuration detected.', ?string $namespace = null, ?string $key = null) @@ -20,11 +25,11 @@ public function __construct(string $message = 'Invalid configuration detected.', parent::__construct($message); } - /** @return array{string|null, int|null} */ + /** @return array{string, int} */ protected function findConfigLine(string $namespace, string $key): array { - $file = "config/$namespace.php"; - $contents = file_get_contents(base_path($file)); + $file = realpath("config/$namespace.php"); + $contents = Filesystem::getContents($file); $lines = explode("\n", $contents); foreach ($lines as $line => $content) { @@ -33,6 +38,9 @@ protected function findConfigLine(string $namespace, string $key): array } } + assert($file !== false); + assert(isset($line)); + return [$file, $line + 1]; } } From f2c667d4c56d1d5e27838e323bd0bfdc575ec590 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Sun, 7 Jul 2024 15:22:09 +0200 Subject: [PATCH 10/16] Inline local variables --- .../Framework/Exceptions/InvalidConfigurationException.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php b/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php index 8a6f7722492..1ea898af91f 100644 --- a/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php +++ b/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php @@ -16,10 +16,7 @@ class InvalidConfigurationException extends InvalidArgumentException public function __construct(string $message = 'Invalid configuration detected.', ?string $namespace = null, ?string $key = null) { if ($namespace && $key) { - [$file, $line] = $this->findConfigLine($namespace, $key); - - $this->file = $file; - $this->line = $line; + [$this->file, $this->line] = $this->findConfigLine($namespace, $key); } parent::__construct($message); From dc495d1ff20bb35803ffc4a1e12f236995d756ae Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Sun, 7 Jul 2024 15:23:46 +0200 Subject: [PATCH 11/16] Mark helper as experimental --- .../Framework/Exceptions/InvalidConfigurationException.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php b/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php index 1ea898af91f..67a13ba331c 100644 --- a/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php +++ b/packages/framework/src/Framework/Exceptions/InvalidConfigurationException.php @@ -22,7 +22,11 @@ public function __construct(string $message = 'Invalid configuration detected.', parent::__construct($message); } - /** @return array{string, int} */ + /** + * @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"); From 7e912288494f294095c323e229150316ccde7442 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Sun, 7 Jul 2024 15:31:41 +0200 Subject: [PATCH 12/16] Test covers InvalidConfigurationException --- packages/framework/tests/Unit/CustomExceptionsTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/framework/tests/Unit/CustomExceptionsTest.php b/packages/framework/tests/Unit/CustomExceptionsTest.php index 38be357f085..8b6e94e5831 100644 --- a/packages/framework/tests/Unit/CustomExceptionsTest.php +++ b/packages/framework/tests/Unit/CustomExceptionsTest.php @@ -19,6 +19,7 @@ * @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 From 07fc54208f09aeadad6a149485a9c451ddb71c80 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Sun, 7 Jul 2024 15:35:28 +0200 Subject: [PATCH 13/16] Generate tests with Claude --- .../tests/Unit/CustomExceptionsTest.php | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/packages/framework/tests/Unit/CustomExceptionsTest.php b/packages/framework/tests/Unit/CustomExceptionsTest.php index 8b6e94e5831..f2a1bd38b77 100644 --- a/packages/framework/tests/Unit/CustomExceptionsTest.php +++ b/packages/framework/tests/Unit/CustomExceptionsTest.php @@ -13,6 +13,7 @@ use Hyde\Framework\Exceptions\ParseException; use RuntimeException; use Exception; +use Hyde\Framework\Exceptions\InvalidConfigurationException; /** * @covers \Hyde\Framework\Exceptions\FileConflictException @@ -174,4 +175,55 @@ 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.', 'app', 'debug'); + + $this->assertSame('Invalid configuration.', $exception->getMessage()); + $this->assertFileExists($exception->file); + $this->assertIsInt($exception->line); + } + + public function testInvalidConfigurationExceptionWithNonExistentNamespace() + { + $this->expectException(\AssertionError::class); + new InvalidConfigurationException('Invalid configuration.', 'non_existent', 'key'); + } + + public function testInvalidConfigurationExceptionWithNonExistentKey() + { + $this->expectException(\AssertionError::class); + new InvalidConfigurationException('Invalid configuration.', 'app', 'non_existent_key'); + } + + public function testInvalidConfigurationExceptionFindConfigLine() + { + $exception = new class('Invalid configuration.', 'app', 'debug') extends InvalidConfigurationException { + public function exposedFindConfigLine(string $namespace, string $key): array + { + return $this->findConfigLine($namespace, $key); + } + }; + + [$file, $line] = $exception->exposedFindConfigLine('app', 'debug'); + + $this->assertFileExists($file); + $this->assertIsInt($line); + $this->assertGreaterThan(0, $line); + } } From 29234ce757bf150f3593a745eccf562ebec6bfe1 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Sun, 7 Jul 2024 15:37:24 +0200 Subject: [PATCH 14/16] Fix up generated tests --- .../framework/tests/Unit/CustomExceptionsTest.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/framework/tests/Unit/CustomExceptionsTest.php b/packages/framework/tests/Unit/CustomExceptionsTest.php index f2a1bd38b77..fad2c5e664e 100644 --- a/packages/framework/tests/Unit/CustomExceptionsTest.php +++ b/packages/framework/tests/Unit/CustomExceptionsTest.php @@ -192,11 +192,14 @@ public function testInvalidConfigurationExceptionWithCustomMessage() public function testInvalidConfigurationExceptionWithNamespaceAndKey() { - $exception = new InvalidConfigurationException('Invalid configuration.', 'app', 'debug'); + $exception = new InvalidConfigurationException('Invalid configuration.', 'hyde', 'name'); $this->assertSame('Invalid configuration.', $exception->getMessage()); - $this->assertFileExists($exception->file); - $this->assertIsInt($exception->line); + $this->assertFileExists($exception->getFile()); + $this->assertIsInt($exception->getLine()); + + $this->assertStringContainsString('config'.DIRECTORY_SEPARATOR.'hyde.php', $exception->getFile()); + $this->assertGreaterThan(0, $exception->getLine()); } public function testInvalidConfigurationExceptionWithNonExistentNamespace() @@ -213,7 +216,7 @@ public function testInvalidConfigurationExceptionWithNonExistentKey() public function testInvalidConfigurationExceptionFindConfigLine() { - $exception = new class('Invalid configuration.', 'app', 'debug') extends InvalidConfigurationException { + $exception = new class('Invalid configuration.', 'hyde', 'name') extends InvalidConfigurationException { public function exposedFindConfigLine(string $namespace, string $key): array { return $this->findConfigLine($namespace, $key); From 3083c7f0230da7f42dd449c2e05691a59f8e9be9 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Sun, 7 Jul 2024 15:37:37 +0200 Subject: [PATCH 15/16] Remove unnecessary tests --- .../tests/Unit/CustomExceptionsTest.php | 28 ------------------- 1 file changed, 28 deletions(-) diff --git a/packages/framework/tests/Unit/CustomExceptionsTest.php b/packages/framework/tests/Unit/CustomExceptionsTest.php index fad2c5e664e..dc6e9b460f7 100644 --- a/packages/framework/tests/Unit/CustomExceptionsTest.php +++ b/packages/framework/tests/Unit/CustomExceptionsTest.php @@ -201,32 +201,4 @@ public function testInvalidConfigurationExceptionWithNamespaceAndKey() $this->assertStringContainsString('config'.DIRECTORY_SEPARATOR.'hyde.php', $exception->getFile()); $this->assertGreaterThan(0, $exception->getLine()); } - - public function testInvalidConfigurationExceptionWithNonExistentNamespace() - { - $this->expectException(\AssertionError::class); - new InvalidConfigurationException('Invalid configuration.', 'non_existent', 'key'); - } - - public function testInvalidConfigurationExceptionWithNonExistentKey() - { - $this->expectException(\AssertionError::class); - new InvalidConfigurationException('Invalid configuration.', 'app', 'non_existent_key'); - } - - public function testInvalidConfigurationExceptionFindConfigLine() - { - $exception = new class('Invalid configuration.', 'hyde', 'name') extends InvalidConfigurationException { - public function exposedFindConfigLine(string $namespace, string $key): array - { - return $this->findConfigLine($namespace, $key); - } - }; - - [$file, $line] = $exception->exposedFindConfigLine('app', 'debug'); - - $this->assertFileExists($file); - $this->assertIsInt($line); - $this->assertGreaterThan(0, $line); - } } From f8c884797c198665aa71058caa927d6c4a0b4055 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Sun, 7 Jul 2024 15:39:40 +0200 Subject: [PATCH 16/16] Update RELEASE_NOTES.md --- RELEASE_NOTES.md | 1 + 1 file changed, 1 insertion(+) 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