'Invalid error code', 10001 => 'Unknown error; escaping', 10002 => 'Incorrect number of parameters for Exception message; %s expected', 10101 => '%s is an invalid Stack index', 10102 => 'Element, Document, or DOMDocumentFragment expected for fragment context; found %s', 10201 => 'Data string expected; found %s', 10202 => '%s is an invalid data consumption length; a value of 1 or above is expected', 10301 => 'The first argument must either be an instance of \DOMNode, a string, or a closure; found %s', 10302 => 'Element, Document, or DOMDocumentFragment expected; found %s', 10401 => 'The Tokenizer has entered an invalid state', 10501 => 'Form element expected, found %s', 10502 => 'Element, Document, or DOMDocumentFragment expected; found %s', 10601 => 'Non-empty Document supplied as argument for Parser']; public function __construct(int $code, ...$args) { if (!isset(static::$messages[$code])) { throw new Exception(self::INVALID_CODE); } $message = static::$messages[$code]; $previous = null; // Grab a previous exception if there is one. if ($args[0] instanceof \Throwable) { $previous = array_shift($args); } elseif (end($args) instanceof \Throwable) { $previous = array_pop($args); } // Count the number of replacements needed in the message. $count = substr_count($message, '%s'); // If the number of replacements don't match the arguments then oops. if (count($args) !== $count) { throw new Exception(self::INCORRECT_PARAMETERS_FOR_MESSAGE, $count); } if ($count > 0) { // Go through each of the arguments and run sprintf on the strings. $message = call_user_func_array('sprintf', array_merge([$message], $args)); } parent::__construct($message, $code, $previous); } }