diff --git a/src/DI/Compiler.php b/src/DI/Compiler.php index 44f294928..dfe360540 100644 --- a/src/DI/Compiler.php +++ b/src/DI/Compiler.php @@ -179,9 +179,12 @@ public function processExtensions() $extra = implode("', '", array_keys($extra)); throw new Nette\DeprecatedException("Extensions '$extra' were added while container was being compiled."); - } elseif ($extra = array_diff_key($this->config, self::$reserved, $this->extensions)) { - $extra = implode("', '", array_keys($extra)); - throw new Nette\InvalidStateException("Found sections '$extra' in configuration, but corresponding extensions are missing."); + } elseif ($extra = key(array_diff_key($this->config, self::$reserved, $this->extensions))) { + $hint = Nette\Utils\ObjectMixin::getSuggestion(array_keys(self::$reserved + $this->extensions), $extra); + throw new Nette\InvalidStateException( + "Found section '$extra' in configuration, but corresponding extension is missing" + . ($hint ? ", did you mean '$hint'?" : '.') + ); } } diff --git a/src/DI/CompilerExtension.php b/src/DI/CompilerExtension.php index f2ad3481f..8f50457e4 100644 --- a/src/DI/CompilerExtension.php +++ b/src/DI/CompilerExtension.php @@ -65,8 +65,9 @@ public function validateConfig(array $expected, array $config = NULL, $name = NU } if ($extra = array_diff_key((array) $config, $expected)) { $name = $name ?: $this->name; - $extra = implode(", $name.", array_keys($extra)); - throw new Nette\InvalidStateException("Unknown configuration option $name.$extra."); + $hint = Nette\Utils\ObjectMixin::getSuggestion(array_keys($expected), key($extra)); + $extra = $hint ? key($extra) : implode(", $name.", array_keys($extra)); + throw new Nette\InvalidStateException("Unknown configuration option $name.$extra" . ($hint ? ", did you mean $name.$hint?" : '.')); } return Config\Helpers::merge($config, $expected); } diff --git a/tests/DI/CompilerExtension.validateConfig.phpt b/tests/DI/CompilerExtension.validateConfig.phpt index 7d1779140..3f57dd6ee 100644 --- a/tests/DI/CompilerExtension.validateConfig.phpt +++ b/tests/DI/CompilerExtension.validateConfig.phpt @@ -47,15 +47,15 @@ test(function () { Assert::exception(function () { $ext = new MyExtension; $ext->validateConfig(['a' => 1, 'b' => 1], ['c' => 1]); -}, Nette\InvalidStateException::class, 'Unknown configuration option my.c.'); +}, Nette\InvalidStateException::class, 'Unknown configuration option my.c, did you mean my.a?'); Assert::exception(function () { $ext = new MyExtension; $ext->validateConfig(['a' => 1, 'b' => 1], ['c' => 1, 'd' => 1], 'name'); -}, Nette\InvalidStateException::class, 'Unknown configuration option name.c, name.d.'); +}, Nette\InvalidStateException::class, 'Unknown configuration option name.c, did you mean name.a?'); Assert::exception(function () { $ext = new MyExtension; $ext->setConfig(['c' => 1, 'd' => 1]); $ext->validateConfig(['a' => 1, 'b' => 1]); -}, Nette\InvalidStateException::class, 'Unknown configuration option my.c, my.d.'); +}, Nette\InvalidStateException::class, 'Unknown configuration option my.c, did you mean my.a?');