Надо ли бросать исключение при приеме ошибочных (невалидных) данных?
Да, нужно, в большинстве случаев. Можно создать класс ValidationException, который принимает в конструкторе массив сообщений с ошибками и унаследовать его от класса Exception:class ValidationException extends Exception
{
    /**
     * Validation error messages.
     * 
     * @var array
     */
    protected $errors = [];

    /**
     * Constructor.
     * 
     * @param array $errors
     */
    public function __construct($errors)
    {
        $this -> errors = $errors;
    }

    /* геттер для свойства $errors */
}
Да, нужно, в большинстве случаев. Можно создать класс ValidationException, который принимает в конструкторе массив сообщений с ошибками и унаследовать его от класса Exception:class ValidationException extends Exception
{
    /**
     * Validation error messages.
     * 
     * @var array
     */
    protected $errors = [];

    /**
     * Constructor.
     * 
     * @param array $errors
     */
    public function __construct($errors)
    {
        $this -> errors = $errors;
    }

    /* геттер для свойства $errors */
}