Repository: FriendsOfPHP/PHP-CS-Fixer (php)

Issue:
Too few arguments to function PhpCsFixer\ConfigurationException\InvalidFixerConfigurationException
## Bug report

When I try to migrate my code, it crashes:

```ShellSession
$ PHP_CS_FIXER_FUTURE_MODE=1 php-cs-fixer fix -vvv
PHP CS Fixer 2.19.0 Testament by Fabien Potencier and Dariusz Ruminski
Runtime: PHP 7.4.18
Loaded config default from "/home/jtojnar/Projects/guzzle-transcoder/.php-cs-fixer.php".
Using cache file ".php_cs.cache".

Fatal error: Uncaught ArgumentCountError: Too few arguments to function PhpCsFixer\ConfigurationException\InvalidFixerConfigurationException::__construct(), 1 passed in /home/jtojnar/Projects/guzzle-transcoder/vendor/friendsofphp/php-cs-fixer/src/Utils.php on line 197 and at least 2 expected in /home/jtojnar/Projects/guzzle-transcoder/vendor/friendsofphp/php-cs-fixer/src/ConfigurationException/InvalidFixerConfigurationException.php:37
Stack trace:
#0 /home/jtojnar/Projects/guzzle-transcoder/vendor/friendsofphp/php-cs-fixer/src/Utils.php(197): PhpCsFixer\ConfigurationException\InvalidFixerConfigurationException->__construct('To disable the ...')
#1 /home/jtojnar/Projects/guzzle-transcoder/vendor/friendsofphp/php-cs-fixer/src/RuleSet/RuleSet.php(57): PhpCsFixer\Utils::triggerDeprecation('To disable the ...', 'PhpCsFixer\\Conf...')
#2 /home/jtojnar/Projects/guzzle-transcoder/vendor/friendsofphp/php-cs-fixer/src/Console/ConfigurationResolver.php(671): PhpCsFixer\RuleSet\RuleSet->__construct(Array)
#3 /home/jtojnar/Projects/gu in /home/jtojnar/Projects/guzzle-transcoder/vendor/friendsofphp/php-cs-fixer/src/ConfigurationException/InvalidFixerConfigurationException.php on line 37
```

No error without future mode.

Looks like the `null` rule is the culprit:


```php
<?php

$finder = PhpCsFixer\Finder::create()
    ->in(__DIR__);

$rules = [
    'yoda_style' => null,
];

$config = new PhpCsFixer\Config();

return $config
    ->setRules($rules)
    ->setFinder($finder);
```


Pull request:
Fix transforming deprecations into exceptions
Fixes #5729.

Patch:
diff --git a/src/AbstractFixer.php b/src/AbstractFixer.php
index 6ae3b8a8c..7ce3f48e9 100644
--- a/src/AbstractFixer.php
+++ b/src/AbstractFixer.php
@@ -118,10 +118,9 @@ public function configure(array $configuration = null)
         }
 
         if (null === $configuration) {
-            Utils::triggerDeprecation(
-                'Passing NULL to set default configuration is deprecated and will not be supported in 3.0, use an empty array instead.',
-                \InvalidArgumentException::class
-            );
+            Utils::triggerDeprecation(new \InvalidArgumentException(
+                'Passing NULL to set default configuration is deprecated and will not be supported in 3.0, use an empty array instead.'
+            ));
 
             $configuration = [];
         }
@@ -133,16 +132,13 @@ public function configure(array $configuration = null)
 
             $name = $option->getName();
             if (\array_key_exists($name, $configuration)) {
-                Utils::triggerDeprecation(
-                    sprintf(
-                        'Option "%s" for rule "%s" is deprecated and will be removed in version %d.0. %s',
-                        $name,
-                        $this->getName(),
-                        Application::getMajorVersion() + 1,
-                        str_replace('`', '"', $option->getDeprecationMessage())
-                    ),
-                    \InvalidArgumentException::class
-                );
+                Utils::triggerDeprecation(new \InvalidArgumentException(sprintf(
+                    'Option "%s" for rule "%s" is deprecated and will be removed in version %d.0. %s',
+                    $name,
+                    $this->getName(),
+                    Application::getMajorVersion() + 1,
+                    str_replace('`', '"', $option->getDeprecationMessage())
+                )));
             }
         }
 
diff --git a/src/Config.php b/src/Config.php
index b159e258b..347d56ddd 100644
--- a/src/Config.php
+++ b/src/Config.php
@@ -46,7 +46,7 @@ public function __construct($name = 'default')
      */
     public static function create()
     {
-        Utils::triggerDeprecation(__METHOD__.' is deprecated since 2.17 and will be removed in 3.0.');
+        Utils::triggerDeprecation(new \RuntimeException(__METHOD__.' is deprecated since 2.17 and will be removed in 3.0.'));
 
         return new static();
     }
diff --git a/src/Console/ConfigurationResolver.php b/src/Console/ConfigurationResolver.php
index 0728ad292..f479dfd94 100644
--- a/src/Console/ConfigurationResolver.php
+++ b/src/Console/ConfigurationResolver.php
@@ -235,7 +235,7 @@ public function getConfig()
 
                 if (isset($deprecatedConfigs[$configFileBasename])) {
                     $message = "Configuration file `{$configFileBasename}` is deprecated, rename to `{$deprecatedConfigs[$configFileBasename]}`.";
-                    Utils::triggerDeprecation($message, InvalidConfigurationException::class);
+                    Utils::triggerDeprecation(new InvalidConfigurationException($message));
                 }
 
                 $config = self::separatedContextLessInclude($configFile);
@@ -457,10 +457,9 @@ public function getProgress()
                         implode('", "', $progressTypes)
                     ));
                 } elseif (\in_array($progressType, ['estimating', 'estimating-max', 'run-in'], true)) {
-                    Utils::triggerDeprecation(
-                        'Passing `estimating`, `estimating-max` or `run-in` is deprecated and will not be supported in 3.0, use `none` or `dots` instead.',
-                        \InvalidArgumentException::class
-                    );
+                    Utils::triggerDeprecation(new \InvalidArgumentException(
+                        'Passing `estimating`, `estimating-max` or `run-in` is deprecated and will not be supported in 3.0, use `none` or `dots` instead.'
+                    ));
                 }
 
                 $this->progress = $progressType;
@@ -798,7 +797,7 @@ private function validateRules(array $rules)
                     ? sprintf(' and will be removed in version %d.0.', Application::getMajorVersion() + 1)
                     : sprintf('. Use %s instead.', str_replace('`', '"', Utils::naturalLanguageJoinWithBackticks($successors)));
 
-                Utils::triggerDeprecation("Rule \"{$fixerName}\" is deprecated{$messageEnd}");
+                Utils::triggerDeprecation(new \RuntimeException("Rule \"{$fixerName}\" is deprecated{$messageEnd}"));
             }
         }
     }
@@ -944,10 +943,9 @@ private function resolveOptionBooleanValue($optionName)
             return false;
         }
 
-        Utils::triggerDeprecation(
-            sprintf('Expected "yes" or "no" for option "%s", other values are deprecated and support will be removed in 3.0. Got "%s", this implicitly set the option to "false".', $optionName, $value),
-            InvalidConfigurationException::class
-        );
+        Utils::triggerDeprecation(new InvalidConfigurationException(
+            sprintf('Expected "yes" or "no" for option "%s", other values are deprecated and support will be removed in 3.0. Got "%s", this implicitly set the option to "false".', $optionName, $value)
+        ));
 
         return false;
     }
diff --git a/src/Fixer/ClassNotation/ClassAttributesSeparationFixer.php b/src/Fixer/ClassNotation/ClassAttributesSeparationFixer.php
index 709e677e2..7ddc959e6 100644
--- a/src/Fixer/ClassNotation/ClassAttributesSeparationFixer.php
+++ b/src/Fixer/ClassNotation/ClassAttributesSeparationFixer.php
@@ -194,7 +194,9 @@ protected function createConfigurationDefinition()
                 ->setNormalizer(static function (Options $options, $values) {
                     $deprecated = array_intersect($values, self::SUPPORTED_TYPES);
                     if (\count($deprecated) > 0) {
-                        Utils::triggerDeprecation('A list of elements is deprecated, use a dictionary of `const|method|property` => `none|one` instead.');
+                        Utils::triggerDeprecation(new \RuntimeException(
+                            'A list of elements is deprecated, use a dictionary of `const|method|property` => `none|one` instead.'
+                        ));
 
                         return array_fill_keys($deprecated, self::SPACING_ONE);
                     }
diff --git a/src/Fixer/FunctionNotation/MethodArgumentSpaceFixer.php b/src/Fixer/FunctionNotation/MethodArgumentSpaceFixer.php
index efeaa406d..971eca6e3 100644
--- a/src/Fixer/FunctionNotation/MethodArgumentSpaceFixer.php
+++ b/src/Fixer/FunctionNotation/MethodArgumentSpaceFixer.php
@@ -43,7 +43,7 @@ final class MethodArgumentSpaceFixer extends AbstractFixer implements Configurat
      */
     public function fixSpace(Tokens $tokens, $index)
     {
-        Utils::triggerDeprecation(__METHOD__.' is deprecated and will be removed in 3.0.');
+        Utils::triggerDeprecation(new \RuntimeException(__METHOD__.' is deprecated and will be removed in 3.0.'));
         $this->fixSpace2($tokens, $index);
     }
 
diff --git a/src/Fixer/Operator/AlignDoubleArrowFixerHelper.php b/src/Fixer/Operator/AlignDoubleArrowFixerHelper.php
index a28d9fb7b..483553c47 100644
--- a/src/Fixer/Operator/AlignDoubleArrowFixerHelper.php
+++ b/src/Fixer/Operator/AlignDoubleArrowFixerHelper.php
@@ -38,12 +38,10 @@ final class AlignDoubleArrowFixerHelper extends AbstractAlignFixerHelper
 
     public function __construct()
     {
-        Utils::triggerDeprecation(
-            sprintf(
-                'The "%s" class is deprecated. You should stop using it, as it will be removed in 3.0 version.',
-                __CLASS__
-            )
-        );
+        Utils::triggerDeprecation(new \RuntimeException(sprintf(
+            'The "%s" class is deprecated. You should stop using it, as it will be removed in 3.0 version.',
+            __CLASS__
+        )));
     }
 
     /**
diff --git a/src/Fixer/Operator/AlignEqualsFixerHelper.php b/src/Fixer/Operator/AlignEqualsFixerHelper.php
index 656e6cb0d..330c72def 100644
--- a/src/Fixer/Operator/AlignEqualsFixerHelper.php
+++ b/src/Fixer/Operator/AlignEqualsFixerHelper.php
@@ -28,12 +28,10 @@ final class AlignEqualsFixerHelper extends AbstractAlignFixerHelper
 {
     public function __construct()
     {
-        Utils::triggerDeprecation(
-            sprintf(
-                'The "%s" class is deprecated. You should stop using it, as it will be removed in 3.0 version.',
-                __CLASS__
-            )
-        );
+        Utils::triggerDeprecation(new \RuntimeException(sprintf(
+            'The "%s" class is deprecated. You should stop using it, as it will be removed in 3.0 version.',
+            __CLASS__
+        )));
     }
 
     /**
diff --git a/src/Fixer/Operator/BinaryOperatorSpacesFixer.php b/src/Fixer/Operator/BinaryOperatorSpacesFixer.php
index 6fae35600..7656967e2 100644
--- a/src/Fixer/Operator/BinaryOperatorSpacesFixer.php
+++ b/src/Fixer/Operator/BinaryOperatorSpacesFixer.php
@@ -555,14 +555,14 @@ private function resolveOldConfig(array $configuration)
             }
         }
 
-        Utils::triggerDeprecation(
+        Utils::triggerDeprecation(new InvalidFixerConfigurationException(
+            $this->getName(),
             sprintf(
                 'Given configuration is deprecated and will be removed in 3.0. Use configuration %s as replacement for %s.',
                 HelpCommand::toString($newConfig),
                 HelpCommand::toString($configuration)
-            ),
-            InvalidFixerConfigurationException::class
-        );
+            )
+        ));
 
         return $newConfig;
     }
diff --git a/src/Fixer/Whitespace/BlankLineBeforeStatementFixer.php b/src/Fixer/Whitespace/BlankLineBeforeStatementFixer.php
index 25d9e6c9a..abde1599d 100644
--- a/src/Fixer/Whitespace/BlankLineBeforeStatementFixer.php
+++ b/src/Fixer/Whitespace/BlankLineBeforeStatementFixer.php
@@ -89,7 +89,7 @@ public function configure(array $configuration = null)
 
         foreach ($this->configuration['statements'] as $key) {
             if ('die' === $key) {
-                Utils::triggerDeprecation('Option "die" is deprecated, use "exit" instead.');
+                Utils::triggerDeprecation(new \RuntimeException('Option "die" is deprecated, use "exit" instead.'));
             }
 
             $this->fixTokenMap[$key] = self::$tokenMap[$key];
diff --git a/src/Fixer/Whitespace/NoExtraBlankLinesFixer.php b/src/Fixer/Whitespace/NoExtraBlankLinesFixer.php
index 8077f2729..64bed1611 100644
--- a/src/Fixer/Whitespace/NoExtraBlankLinesFixer.php
+++ b/src/Fixer/Whitespace/NoExtraBlankLinesFixer.php
@@ -320,10 +320,9 @@ protected function createConfigurationDefinition()
                 ->setNormalizer(static function (Options $options, $tokens) use ($that) {
                     foreach ($tokens as &$token) {
                         if ('useTrait' === $token) {
-                            Utils::triggerDeprecation(
-                                "Token \"useTrait\" in option \"tokens\" for rule \"{$that->getName()}\" is deprecated and will be removed in 3.0, use \"use_trait\" instead.",
-                                InvalidConfigurationException::class
-                            );
+                            Utils::triggerDeprecation(new InvalidConfigurationException(
+                                "Token \"useTrait\" in option \"tokens\" for rule \"{$that->getName()}\" is deprecated and will be removed in 3.0, use \"use_trait\" instead."
+                            ));
                             $token = 'use_trait';
 
                             break;
diff --git a/src/FixerConfiguration/FixerConfigurationResolver.php b/src/FixerConfiguration/FixerConfigurationResolver.php
index 21a24149f..7d07b2d5c 100644
--- a/src/FixerConfiguration/FixerConfigurationResolver.php
+++ b/src/FixerConfiguration/FixerConfigurationResolver.php
@@ -68,7 +68,11 @@ public function resolve(array $options)
                         throw new InvalidOptionsException(sprintf('Aliased option "%s"/"%s" is passed multiple times.', $name, $alias));
                     }
 
-                    Utils::triggerDeprecation(sprintf('Option "%s" is deprecated, use "%s" instead.', $alias, $name));
+                    Utils::triggerDeprecation(new \RuntimeException(sprintf(
+                        'Option "%s" is deprecated, use "%s" instead.',
+                        $alias,
+                        $name
+                    )));
 
                     $options[$name] = $options[$alias];
                     unset($options[$alias]);
diff --git a/src/FixerConfiguration/FixerConfigurationResolverRootless.php b/src/FixerConfiguration/FixerConfigurationResolverRootless.php
index 497078e2c..46437d232 100644
--- a/src/FixerConfiguration/FixerConfigurationResolverRootless.php
+++ b/src/FixerConfiguration/FixerConfigurationResolverRootless.php
@@ -84,7 +84,9 @@ static function (FixerOptionInterface $option) {
             $passedNames = array_keys($options);
 
             if (!empty(array_diff($passedNames, $names))) {
-                Utils::triggerDeprecation("Passing \"{$this->root}\" at the root of the configuration for rule \"{$this->fixerName}\" is deprecated and will not be supported in 3.0, use \"{$this->root}\" => array(...) option instead.");
+                Utils::triggerDeprecation(new \RuntimeException(
+                    "Passing \"{$this->root}\" at the root of the configuration for rule \"{$this->fixerName}\" is deprecated and will not be supported in 3.0, use \"{$this->root}\" => array(...) option instead."
+                ));
 
                 $options = [$this->root => $options];
             }
diff --git a/src/FixerDefinition/FixerDefinition.php b/src/FixerDefinition/FixerDefinition.php
index 59dd04c3a..99c87c422 100644
--- a/src/FixerDefinition/FixerDefinition.php
+++ b/src/FixerDefinition/FixerDefinition.php
@@ -43,9 +43,9 @@ public function __construct(
         $riskyDescription = null
     ) {
         if (6 === \func_num_args()) {
-            Utils::triggerDeprecation('Arguments #5 and #6 of FixerDefinition::__construct() are deprecated and will be removed in 3.0, use argument #4 instead.');
+            Utils::triggerDeprecation(new \RuntimeException('Arguments #5 and #6 of FixerDefinition::__construct() are deprecated and will be removed in 3.0, use argument #4 instead.'));
         } elseif (5 === \func_num_args()) {
-            Utils::triggerDeprecation('Argument #5 of FixerDefinition::__construct() is deprecated and will be removed in 3.0.');
+            Utils::triggerDeprecation(new \RuntimeException('Argument #5 of FixerDefinition::__construct() is deprecated and will be removed in 3.0.'));
         } else {
             $riskyDescription = $configurationDescription;
             $configurationDescription = null;
@@ -71,14 +71,20 @@ public function getDescription()
 
     public function getConfigurationDescription()
     {
-        Utils::triggerDeprecation(sprintf('%s is deprecated and will be removed in 3.0.', __METHOD__));
+        Utils::triggerDeprecation(new \RuntimeException(sprintf(
+            '%s is deprecated and will be removed in 3.0.',
+            __METHOD__
+        )));
 
         return $this->configurationDescription;
     }
 
     public function getDefaultConfiguration()
     {
-        Utils::triggerDeprecation(sprintf('%s is deprecated and will be removed in 3.0.', __METHOD__));
+        Utils::triggerDeprecation(new \RuntimeException(sprintf(
+            '%s is deprecated and will be removed in 3.0.',
+            __METHOD__
+        )));
 
         return $this->defaultConfiguration;
     }
diff --git a/src/RuleSet/RuleSet.php b/src/RuleSet/RuleSet.php
index 01d183db8..d24628a97 100644
--- a/src/RuleSet/RuleSet.php
+++ b/src/RuleSet/RuleSet.php
@@ -52,10 +52,10 @@ public function __construct(array $set = [])
             if (true !== $value && false !== $value && !\is_array($value)) {
                 // @TODO drop me on 3.0
                 if (null === $value) {
-                    Utils::triggerDeprecation(
-                        'To disable the rule, use "FALSE" instead of "NULL".',
-                        InvalidFixerConfigurationException::class
-                    );
+                    Utils::triggerDeprecation(new InvalidFixerConfigurationException(
+                        $name,
+                        'To disable the rule, use "FALSE" instead of "NULL".'
+                    ));
 
                     continue;
                 }
@@ -106,7 +106,7 @@ public function getRules()
      */
     public static function create(array $set = [])
     {
-        Utils::triggerDeprecation(__METHOD__.' is deprecated and will be removed in 3.0, use the constructor.');
+        Utils::triggerDeprecation(new \RuntimeException(__METHOD__.' is deprecated and will be removed in 3.0, use the constructor.'));
 
         return new self($set);
     }
@@ -116,7 +116,7 @@ public static function create(array $set = [])
      */
     public function getSetDefinitionNames()
     {
-        Utils::triggerDeprecation(__METHOD__.' is deprecated and will be removed in 3.0, use PhpCsFixer\RuleSet\RuleSets::getSetDefinitionNames.');
+        Utils::triggerDeprecation(new \RuntimeException(__METHOD__.' is deprecated and will be removed in 3.0, use PhpCsFixer\RuleSet\RuleSets::getSetDefinitionNames.'));
 
         return RuleSets::getSetDefinitionNames();
     }
diff --git a/src/Tokenizer/Token.php b/src/Tokenizer/Token.php
index ef59f3476..2f0ded177 100644
--- a/src/Tokenizer/Token.php
+++ b/src/Tokenizer/Token.php
@@ -143,7 +143,7 @@ public static function getObjectOperatorKinds()
      */
     public function clear()
     {
-        Utils::triggerDeprecation(__METHOD__.' is deprecated and will be removed in 3.0.');
+        Utils::triggerDeprecation(new \RuntimeException(__METHOD__.' is deprecated and will be removed in 3.0.'));
         Tokens::setLegacyMode(true);
 
         $this->content = '';
@@ -158,7 +158,7 @@ public function clear()
      */
     public function clearChanged()
     {
-        Utils::triggerDeprecation(__METHOD__.' is deprecated and will be removed in 3.0.');
+        Utils::triggerDeprecation(new \RuntimeException(__METHOD__.' is deprecated and will be removed in 3.0.'));
         Tokens::setLegacyMode(true);
 
         $this->changed = false;
@@ -417,7 +417,7 @@ public function isCast()
      */
     public function isChanged()
     {
-        Utils::triggerDeprecation(__METHOD__.' is deprecated and will be removed in 3.0.');
+        Utils::triggerDeprecation(new \RuntimeException(__METHOD__.' is deprecated and will be removed in 3.0.'));
 
         return $this->changed;
     }
@@ -463,7 +463,7 @@ public function isObjectOperator()
      */
     public function isEmpty()
     {
-        Utils::triggerDeprecation(__METHOD__.' is deprecated and will be removed in 3.0.');
+        Utils::triggerDeprecation(new \RuntimeException(__METHOD__.' is deprecated and will be removed in 3.0.'));
 
         return null === $this->id && ('' === $this->content || null === $this->content);
     }
@@ -549,7 +549,7 @@ public function isWhitespace($whitespaces = " \t\n\r\0\x0B")
      */
     public function override($other)
     {
-        Utils::triggerDeprecation(__METHOD__.' is deprecated and will be removed in 3.0.');
+        Utils::triggerDeprecation(new \RuntimeException(__METHOD__.' is deprecated and will be removed in 3.0.'));
         Tokens::setLegacyMode(true);
 
         $prototype = $other instanceof self ? $other->getPrototype() : $other;
@@ -580,7 +580,7 @@ public function override($other)
      */
     public function setContent($content)
     {
-        Utils::triggerDeprecation(__METHOD__.' is deprecated and will be removed in 3.0.');
+        Utils::triggerDeprecation(new \RuntimeException(__METHOD__.' is deprecated and will be removed in 3.0.'));
         Tokens::setLegacyMode(true);
 
         if ($this->content === $content) {
@@ -592,7 +592,7 @@ public function setContent($content)
 
         // setting empty content is clearing the token
         if ('' === $content) {
-            Utils::triggerDeprecation(__METHOD__.' shall not be used to clear token, use Tokens::clearAt instead.');
+            Utils::triggerDeprecation(new \RuntimeException(__METHOD__.' shall not be used to clear token, use Tokens::clearAt instead.'));
             $this->id = null;
             $this->isArray = false;
         }
@@ -617,7 +617,10 @@ public function toArray()
     public function toJson(array $options = null)
     {
         if (null !== $options) {
-            Utils::triggerDeprecation(sprintf('Arguments of "%s()" is deprecated since 2.19 and will be removed in 3.0.', __METHOD__));
+            Utils::triggerDeprecation(new \RuntimeException(sprintf(
+                'Arguments of "%s()" is deprecated since 2.19 and will be removed in 3.0.',
+                __METHOD__
+            )));
         }
 
         $options = $options ? Utils::calculateBitmask($options) : (JSON_PRETTY_PRINT | JSON_NUMERIC_CHECK);
diff --git a/src/Tokenizer/Tokens.php b/src/Tokenizer/Tokens.php
index 6d2e238ff..205991a54 100644
--- a/src/Tokenizer/Tokens.php
+++ b/src/Tokenizer/Tokens.php
@@ -469,9 +469,9 @@ public function findBlockEnd($type, $searchIndex, $findEnd = true)
     {
         if (3 === \func_num_args()) {
             if ($findEnd) {
-                Utils::triggerDeprecation('Argument #3 of Tokens::findBlockEnd is deprecated and will be removed in 3.0, you can safely drop the argument.');
+                Utils::triggerDeprecation(new \RuntimeException('Argument #3 of Tokens::findBlockEnd is deprecated and will be removed in 3.0, you can safely drop the argument.'));
             } else {
-                Utils::triggerDeprecation('Argument #3 of Tokens::findBlockEnd is deprecated and will be removed in 3.0, use Tokens::findBlockStart instead.');
+                Utils::triggerDeprecation(new \RuntimeException('Argument #3 of Tokens::findBlockEnd is deprecated and will be removed in 3.0, use Tokens::findBlockStart instead.'));
             }
         }
 
@@ -1029,7 +1029,7 @@ public function clearAt($index)
      */
     public function overrideAt($index, $token)
     {
-        Utils::triggerDeprecation(__METHOD__.' is deprecated and will be removed in 3.0, use offsetSet instead.');
+        Utils::triggerDeprecation(new \RuntimeException(__METHOD__.' is deprecated and will be removed in 3.0, use offsetSet instead.'));
         self::$isLegacyMode = true;
 
         $this[$index]->override($token);
diff --git a/src/Utils.php b/src/Utils.php
index 39b4525a0..5197bb403 100644
--- a/src/Utils.php
+++ b/src/Utils.php
@@ -190,16 +190,19 @@ public static function naturalLanguageJoinWithBackticks(array $names)
 
     /**
      * Handle triggering deprecation error.
-     *
-     * @param string $message
-     * @param string $exceptionClass
      */
-    public static function triggerDeprecation($message, $exceptionClass = \RuntimeException::class)
+    public static function triggerDeprecation(\Exception $futureException)
     {
         if (getenv('PHP_CS_FIXER_FUTURE_MODE')) {
-            throw new $exceptionClass("{$message} This check was performed as `PHP_CS_FIXER_FUTURE_MODE` env var is set.");
+            throw new \RuntimeException(
+                'Your are using something deprecated, see previous exception. Aborting execution because `PHP_CS_FIXER_FUTURE_MODE` environment variable is set.',
+                0,
+                $futureException
+            );
         }
 
+        $message = $futureException->getMessage();
+
         self::$deprecations[$message] = true;
         @trigger_error($message, E_USER_DEPRECATED);
     }


Test patch:
diff --git a/src/Test/AbstractFixerTestCase.php b/src/Test/AbstractFixerTestCase.php
index 55f7845ec..f947a9301 100644
--- a/src/Test/AbstractFixerTestCase.php
+++ b/src/Test/AbstractFixerTestCase.php
@@ -24,12 +24,12 @@ abstract class AbstractFixerTestCase extends BaseAbstractFixerTestCase
 {
     public function __construct($name = null, array $data = [], $dataName = '')
     {
-        Utils::triggerDeprecation(
+        Utils::triggerDeprecation(new \RuntimeException(
             sprintf(
                 'The "%s" class is deprecated. You should stop using it, as it will be removed in 3.0 version.',
                 __CLASS__
             )
-        );
+        ));
 
         parent::__construct($name, $data, $dataName);
     }
diff --git a/src/Test/AbstractIntegrationTestCase.php b/src/Test/AbstractIntegrationTestCase.php
index ea9f98d6c..a2eeb8d86 100644
--- a/src/Test/AbstractIntegrationTestCase.php
+++ b/src/Test/AbstractIntegrationTestCase.php
@@ -24,12 +24,12 @@ abstract class AbstractIntegrationTestCase extends BaseAbstractIntegrationTestCa
 {
     public function __construct($name = null, array $data = [], $dataName = '')
     {
-        Utils::triggerDeprecation(
+        Utils::triggerDeprecation(new \RuntimeException(
             sprintf(
                 'The "%s" class is deprecated. You should stop using it, as it will be removed in 3.0 version.',
                 __CLASS__
             )
-        );
+        ));
 
         parent::__construct($name, $data, $dataName);
     }
diff --git a/src/Test/AccessibleObject.php b/src/Test/AccessibleObject.php
index 8caf4763d..0d0df4ffe 100644
--- a/src/Test/AccessibleObject.php
+++ b/src/Test/AccessibleObject.php
@@ -29,12 +29,12 @@ final class AccessibleObject
      */
     public function __construct($object)
     {
-        Utils::triggerDeprecation(
+        Utils::triggerDeprecation(new \RuntimeException(
             sprintf(
                 'The "%s" class is deprecated and will be removed in 3.0 version. Use "php-cs-fixer/accessible-object" package instead.',
                 __CLASS__
             )
-        );
+        ));
 
         $this->object = $object;
         $this->reflection = new \ReflectionClass($object);
diff --git a/src/Test/IntegrationCase.php b/src/Test/IntegrationCase.php
index 5937c45fc..87bdb80fc 100644
--- a/src/Test/IntegrationCase.php
+++ b/src/Test/IntegrationCase.php
@@ -57,7 +57,10 @@ public function __construct(
             $inputCode
         );
 
-        Utils::triggerDeprecation(sprintf('The "%s" class is deprecated. You should stop using it, as it will be removed in 3.0 version.', __CLASS__));
+        Utils::triggerDeprecation(new \RuntimeException(sprintf(
+            'The "%s" class is deprecated. You should stop using it, as it will be removed in 3.0 version.',
+            __CLASS__
+        )));
     }
 
     public function hasInputCode()
@@ -117,7 +120,10 @@ public function getTitle()
      */
     public function shouldCheckPriority()
     {
-        Utils::triggerDeprecation(sprintf('The "%s" method is deprecated. You should stop using it, as it will be removed in 3.0 version.', __METHOD__));
+        Utils::triggerDeprecation(new \RuntimeException(sprintf(
+            'The "%s" method is deprecated. You should stop using it, as it will be removed in 3.0 version.',
+            __METHOD__
+        )));
 
         $settings = $this->base->getSettings();
 
diff --git a/tests/Fixer/Operator/BinaryOperatorSpacesFixerTest.php b/tests/Fixer/Operator/BinaryOperatorSpacesFixerTest.php
index d1a5066b3..3a71b4342 100644
--- a/tests/Fixer/Operator/BinaryOperatorSpacesFixerTest.php
+++ b/tests/Fixer/Operator/BinaryOperatorSpacesFixerTest.php
@@ -819,7 +819,7 @@ public function testWrongConfigOldValue()
      */
     public function testWrongConfigOldDeprecated()
     {
-        $this->expectDeprecation("Given configuration is deprecated and will be removed in 3.0. Use configuration ['operators' => ['=' => 'align', '=>' => 'single_space']] as replacement for ['align_equals' => true, 'align_double_arrow' => false].");
+        $this->expectDeprecation("[binary_operator_spaces] Given configuration is deprecated and will be removed in 3.0. Use configuration ['operators' => ['=' => 'align', '=>' => 'single_space']] as replacement for ['align_equals' => true, 'align_double_arrow' => false].");
         $this->fixer->configure([
             'align_equals' => true,
             'align_double_arrow' => false,
@@ -831,7 +831,7 @@ public function testWrongConfigOldDeprecated()
      */
     public function testWrongConfigOldDeprecated2()
     {
-        $this->expectDeprecation("Given configuration is deprecated and will be removed in 3.0. Use configuration ['operators' => ['=' => 'align']] as replacement for ['align_equals' => true, 'align_double_arrow' => null].");
+        $this->expectDeprecation("[binary_operator_spaces] Given configuration is deprecated and will be removed in 3.0. Use configuration ['operators' => ['=' => 'align']] as replacement for ['align_equals' => true, 'align_double_arrow' => null].");
         $this->fixer->configure([
             'align_equals' => true,
             'align_double_arrow' => null,
@@ -843,7 +843,7 @@ public function testWrongConfigOldDeprecated2()
      */
     public function testWrongConfigOldDeprecated3()
     {
-        $this->expectDeprecation("Given configuration is deprecated and will be removed in 3.0. Use configuration ['operators' => ['=>' => 'align']] as replacement for ['align_equals' => null, 'align_double_arrow' => true].");
+        $this->expectDeprecation("[binary_operator_spaces] Given configuration is deprecated and will be removed in 3.0. Use configuration ['operators' => ['=>' => 'align']] as replacement for ['align_equals' => null, 'align_double_arrow' => true].");
         $this->fixer->configure([
             'align_equals' => null,
             'align_double_arrow' => true,
@@ -855,7 +855,7 @@ public function testWrongConfigOldDeprecated3()
      */
     public function testWrongConfigOldDeprecated4()
     {
-        $this->expectDeprecation("Given configuration is deprecated and will be removed in 3.0. Use configuration ['operators' => ['=' => 'single_space', '=>' => 'align']] as replacement for ['align_equals' => false, 'align_double_arrow' => true].");
+        $this->expectDeprecation("[binary_operator_spaces] Given configuration is deprecated and will be removed in 3.0. Use configuration ['operators' => ['=' => 'single_space', '=>' => 'align']] as replacement for ['align_equals' => false, 'align_double_arrow' => true].");
         $this->fixer->configure([
             'align_equals' => false,
             'align_double_arrow' => true,
@@ -867,7 +867,7 @@ public function testWrongConfigOldDeprecated4()
      */
     public function testWrongConfigOldDeprecated5()
     {
-        $this->expectDeprecation("Given configuration is deprecated and will be removed in 3.0. Use configuration ['operators' => ['=' => 'align', '=>' => 'align']] as replacement for ['align_equals' => true, 'align_double_arrow' => true].");
+        $this->expectDeprecation("[binary_operator_spaces] Given configuration is deprecated and will be removed in 3.0. Use configuration ['operators' => ['=' => 'align', '=>' => 'align']] as replacement for ['align_equals' => true, 'align_double_arrow' => true].");
         $this->fixer->configure([
             'align_equals' => true,
             'align_double_arrow' => true,
diff --git a/tests/UtilsTest.php b/tests/UtilsTest.php
index fbf5edc5e..5e32559a6 100644
--- a/tests/UtilsTest.php
+++ b/tests/UtilsTest.php
@@ -313,17 +313,23 @@ public function testTriggerDeprecationWhenFutureModeIsOff()
 
         $this->expectDeprecation('The message');
 
-        Utils::triggerDeprecation('The message', \DomainException::class);
+        Utils::triggerDeprecation(new \DomainException('The message'));
     }
 
     public function testTriggerDeprecationWhenFutureModeIsOn()
     {
         putenv('PHP_CS_FIXER_FUTURE_MODE=1');
 
-        $this->expectException(\DomainException::class);
-        $this->expectExceptionMessage('The message');
+        $exception = new \DomainException('The message');
+        $futureModeException = null;
 
-        Utils::triggerDeprecation('The message', \DomainException::class);
+        try {
+            Utils::triggerDeprecation($exception);
+        } catch (\Exception $futureModeException) {
+        }
+
+        static::assertInstanceOf(\RuntimeException::class, $futureModeException);
+        static::assertSame($exception, $futureModeException->getPrevious());
     }
 
     private function createFixerDouble($name, $priority)