Jak zachytávat vyjímky, které jsou již v bloku try catch v nette core?

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Joacim
Člen | 229
+
0
-

Potřeboval bych použít

use Nette\Database\Connection;
$connection = new Connection($dsn, $user, $password);

S tím, že daný blok dám do try catch a vypíši si svou hlášku místo klasické z fce connect

try {
       $this->pdo = new PDO($this->params[0], $this->params[1], $this->params[2], $this->options);
       $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
       throw ConnectionException::from($e);
}

Jedná se o třídu, která je v nette pressenter/template, takže vše z nette je snadno dostupné.
Touto vyjímkou potřebuji zachytávat kvůli špatně zadaným údajům pro připojení k DB s tím, že vyzvu uživatele k opravě dat přes flash messagess.

Bohužel mě vždy zastaví

$this->pdo = new PDO($this->params[0], $this->params[1], $this->params[2], $this->options);

klasické mysql connect používat nechci nebo se mu chci vyhnout pokud existuje možnost jak obejít nette blok try catch

Editoval Joacim (20. 5. 2015 8:49)

Michal Vyšinský
Člen | 608
+
0
-

Kde máš tento kód? V nějaké třídě s nějakým namespace? Jestli ano, použils use PDOException? Bohužel php je v tomto trochu na nic, protože ti umožní „zachytávat“ exception, která neexistuje. Ale IDE by ti mělo ukázat, že je něco špatně.

Edit: jakou vyjímku ti to nakonec teda vyhodí?

Editoval Michal Vyšinský (20. 5. 2015 8:58)

Joacim
Člen | 229
+
0
-
PDO::__construct(): php_network_getaddresses: getaddrinfo failed: Neznámý hostitel
$this->pdo = new PDO($this->params[0], $this->params[1], $this->params[2], $this->options);

Je to obyč presenter, který kontroluje správnost a případně pak ukládá data, jedná se o Install page mého CMS.

Toto je vyjímka z nette Nette\Database\Connection->connect

Potřebuji jen obejít nette vyjímku a zachytit to ve svojí (zatím v mém presenteru InstallPresenter)

use PDOException

jsem nepoužil, ale v bloku chatch ano a stejně to nevalilo, zastavý se to na catch exception v nette database connections, zkusím použít ještě to use

Editoval Joacim (20. 5. 2015 9:32)

Michal Vyšinský
Člen | 608
+
0
-

A jakou vyjímku ti to vyhazuje? Jestli tam Nette zachytává PDOException a vyhazuje jinou, která není jejím potomkem tak je jasné, že pomocí PDOException ji už nezachytíš.

Michal Vyšinský
Člen | 608
+
+2
-

Jak se tak dívám na kód, tak Nette\Database\ConnectionException je potomkem Nette\Database\DriverException a ta zase Nette\Database\PDOException, takže hádám, že problém bude opravdu v tom chybějícím use.

Editoval Michal Vyšinský (20. 5. 2015 9:46)

Joacim
Člen | 229
+
0
-

Bohužel nefunguje processOfInstall

<?php

namespace App\Presenters;
use Nette,
    Nette\Application\UI\Form,
    Nette\Utils\FileSystem,
    Nette\Database\Connection,
    PDOException;

class InstallPresenter extends NoSecurityPresenter {

    private $database; // database
    private $formValues; // hodnoty z formulare

    protected function createComponentConfiguration() {
        $form = new Form;
        $form->addGroup('Nastavení databázových údajů');
        $form->addText('host', 'Host:')
                ->setRequired('zadejte Host')
                ->getControlPrototype()->setClass('form-control');

        $form->addText('login', 'Login:')
             ->getControlPrototype()->setClass('form-control');

        $form->addPassword('password', 'Heslo:')
             ->getControlPrototype()->setClass('form-control');

        $form->addText('database', 'Databáze:')
             ->setRequired()
             ->getControlPrototype()->setClass('form-control');

        $form->addGroup('Administrátorský účet');
        $form->addText('loginAdmin', 'Login:')
             ->setRequired()
             ->getControlPrototype()->setClass('form-control');

        $form->addPassword('passwordAdmin', 'Heslo:')
             ->setRequired()
             ->getControlPrototype()->setClass('form-control');

        $form->addPassword('passwordAdminOver', 'Potvrď heslo:')
             ->addConditionOn($form['passwordAdmin'], Form::VALID)
             ->addRule(Form::FILLED, 'Heslo znovu')
             ->addRule(Form::EQUAL, 'Hesla se neshodují.', $form['passwordAdmin']);

        $form->addSubmit('send', 'Uložit')
             ->getControlPrototype()->setClass('btn btn-lg btn-primary btn-block')
             ;
        $form->onSuccess[] = array($this, 'processOfInstall');

        $form['passwordAdminOver']->getControlPrototype()->setClass('form-control');
        return $form;
    }
    public function processOfInstall($form, $values) {
      $this->formValues = $values;
      $this->saveToFile();


      try {

          $this->database = new Connection(
          'mysql:host=' . $this->formValues->host . ';dbname=' . $this->formValues->database,
          $this->formValues->login,
          $this->formValues->password,
          array(
            'lazy' => array(''),
            'driverClass' => 'Nette\Database\Drivers\MsSqlDriver'
          ));
        $this->database->query(file_get_contents('../install/script.sql')); // import sql
        $this->database->query('INSERT INTO administrator (login, heslo) VALUES(\'' . $this->formValues->loginAdmin . '\',\'' . \Nette\Security\Passwords::hash($this->formValues->passwordAdmin) . '\')'); // import admin uzivatele
        $this->flashMessage('Děkuji za konfiguraci', 'success');
      }
        catch (PDOException $e) {
            $this->flashMessage('Nepodařilo se připojit k databázi!', "danger");
            $this->redirect("Install:");
        }

    }
    public function saveToFile() {
      $config =  '';
    }

}

Vyhodí vyjímku:

Warning
PDO::__construct(): php_network_getaddresses: getaddrinfo failed: Nen znm dn takov hostitel.
$this->pdo = new PDO($this->params[0], $this->params[1], $this->params[2], $this->options);
...\vendor\nette\database\src\Database\Connection.php:66 source  PDO-> __construct (arguments)
...\vendor\nette\database\src\Database\Connection.php:151 source  Nette\Database\Connection-> connect ()

Nepsal jsem to já, psal to kolega, kterej si to chtěl vyzkoušet.

Editoval Joacim (20. 5. 2015 20:58)

David Matějka
Moderator | 6445
+
0
-

Co znamena „nefunguje“? vyhodi to nejakou chybu? jakou.?

Joacim
Člen | 229
+
0
-

Viz výše:

PDO::__construct(): php_network_getaddresses: getaddrinfo failed: Nen znm dn takov hostitel.
David Matějka
Moderator | 6445
+
0
-

to vypada na nejaky php-wtf. Mne to pri chybnym hostu vyhodi vyjimku. Tipuju, ze to zkousis na windowsu? :) zkus to schvalne spustit na linuxovym serveru, nebo zkus udelat jinou chybu – treba spatny heslo

Joacim
Člen | 229
+
0
-

Simulujeme to oba pod Win 7 WAMP server, ale nahodíme to na linux a uvidíme

Joacim
Člen | 229
+
0
-

Na linuxu odzkoušeno

Warning

PDO::__construct(): php_network_getaddresses: getaddrinfo failed: Name or service not known

Při zadání správných hodnot vše funguje, ale pokud zadáme špatné údaje a potřebujeme pouze zachytit vyjímku, že se jedná o nevalidní data, vyhodí to tuto chybu

Aurielle
Člen | 1281
+
0
-

Neprobublává ti tenhle warning (ne výjimka) do Laděnky při zapnutém $strictMode (už jako výjimka)? Nedíval jsem se do dokumentace PDO, ale Nette pravděpodobně ošetřuje jen výjimky a ne běžné PHP chyby, které nejspíš PDO taky vyvolává, takže bych řekl, že šotek bude v tom.

ondrusu
Člen | 118
+
0
-

Děkujeme všem za váš čas. Ano stačilo vypnout „laděnku“

$configurator->setDebugMode( FALSE );

a výjimka se zobrazuje.

přidal jsem use

use PDOException;
try {
  $this->database = new Connection(
    'mysql:host=' . $this->formValues->host . ';dbname=' . $this->formValues->database,
    $this->formValues->login,
    $this->formValues->password,
    array(
      'lazy' => array(''),
      'driverClass' => 'Nette\Database\Drivers\MsSqlDriver'
    )
  );
  $this->database->query(...); // import sql
}
  catch (PDOException $e) {
      $this->flashMessage('Nepodařilo se připojit k databázi.','danger');
  }

Akorát je zajímavé že když přidám do flushMessage

$this->flashMessage('Nepodařilo se připojit k databázi (' . $e->getMessage() . ').','danger');

že to zobrazí prázdný růžový rámeček (kde má být tato chyba napsána). Asi se bez toho obeju, ale to je normální chování??
Díky ;)

Michal Vyšinský
Člen | 608
+
0
-

A jak v šabloně tu flash message vypisuješ?

Joacim
Člen | 229
+
0
-

Michal Vyšinský napsal(a):

A jak v šabloně tu flash message vypisuješ?

Normálně přes Foreach v template

<div n:if="count($flashes) > 0" id="flashmessages">
    <div n:foreach="$flashes as $flash"
         class="alert alert-{$flash->type}">{$flash->message}
    </div>
</div>

Editoval Joacim (27. 5. 2015 15:00)