zachycení více vyjímek

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

Mám funkci RegisterDomainOneSubmited která po odeslání formuláře udělá několik akcí:

  • dibi::query(‚INSERT INTO users‘, $data); //ulozi do databaze (3x)
  • $proforma->savaProforma(); // ulozeni do souboru (1x)
  • $mail->send(); //(3x)

A poslední věc co to má udělat: Jestli projdou všechny akce bez chyby

  • $this->flashMessage(‚Objednávka byla uložena‘);
  • $this->redirect(‚Default:default‘);

Otázka zní, jde nějak ošetřit hromadně tento blok akcí, že když nastane jedna jediná chyba, zobrazí se znovu ten formulář s hodnotami, varováním o chybě a nepřesměruje se to..

Zkoušel jsem něco ve stylu:

<?php
try {
   funkce1();
   funkce2(); // tady nastane treba chyba, tak se nebude pokracovat, ale vyhodi se chyba?
   funkce3();
   $this->flashMessage('Objednávka byla uložena');
   $this->redirect('Default:default');
}catch  (InvalidStateException $e) {
   echo 'nastala chyba';
}
?>

prakticky se chci vyhnout tomuto:

<?php
if (!funkce1()) {
     echo 'chyba';
}

if (!funkce2()) echo 'chyba2';

if (!$mail->send()) echo 'nedeslal se email';

$this->flashMessage('Objednávka byla uložena');
$this->redirect('Default:default');
?>

Zachytávání vyjíme používám poprvé, tak děkuji za nasměrování..

maarlin
Člen | 207
+
0
-

Osobně jsem to zatím nepotřeboval, a hlavně nevím, zda to zcela vyřeší tvůj problém,

$proforma->savaProforma(); // ulozeni do souboru (1×)

nevím, jak to uložení probíhá a která třída to obsluhuje, jakou výjimku případně může vyhodit

$mail->send(); //(3×)

taky nevím, jak je to s výjimkami u Mail…

ale evidentně jde zachycovat více výjimek najednou:
http://www.w3schools.com/…xception.asp → odstavec Multiple Exceptions, popř. http://www.tuxradar.com/…alphp/19/8/7

<?php
try {
	// check if
	if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE) {
		// throw exception if email is not valid
		throw new customException($email);
	}

	// check for "example" in mail address
	if(strpos($email, "example") !== FALSE) {
		throw new Exception("$email is an example e-mail");
	}
} catch (customException $e) {
	echo $e->errorMessage();
} catch(Exception $e) {
	echo $e->getMessage();
}
?>

Editoval maarlin (18. 2. 2010 11:49)

srigi
Nette Blogger | 559
+
0
-

zacatecnik napsal(a):
Otázka zní, jde nějak ošetřit hromadně tento blok akcí, že když nastane jedna jediná chyba, zobrazí se znovu ten formulář s hodnotami, varováním o chybě a nepřesměruje se to..

Zkoušel jsem něco ve stylu:

<?php
try {
   funkce1();
   funkce2(); // tady nastane treba chyba, tak se nebude pokracovat, ale vyhodi se chyba?
   funkce3();
   $this->flashMessage('Objednávka byla uložena');
   $this->redirect('Default:default');
}catch  (InvalidStateException $e) {
   echo 'nastala chyba';
}
?>

Bezne sa to robi cca takto (inspirovane Zend Framework)

<?php
try {
   if (!funkce1()) {
      throw new NejakyTypException('message', ERR_CODE);
   }

   if (!funkce2()) {
      throw new NejakyInyTypException('message', ERR_CODE);
   }

   if (!funkce3()) {
      throw new NejakyDalsiTypException('message', ERR_CODE);
   }

   $this->flashMessage('Objednávka byla uložena');
   $this->redirect('Default:default');
} catch  (NejakyTypException $e) {
   echo 'nastala chyba';
} catch  (NejakyInyTypException $e) {
   echo 'nastala chyba';
} catch  (NejakyDalsiTypException $e) {
   echo 'nastala chyba';
}
?>

Cize tvoje fnce musia vracat ‚truthy‘ alebo ‚falsy‘ hodnoty. Pripadne mozes tie vynimky vyhadzovat uz v tych funkciach. Vynimky maju ty vyhodu, ze prebublavaju hore az kym ich nezachyti nejaky adekvatny CATCH blok.

Editoval srigi (18. 2. 2010 13:32)

redhead
Člen | 1313
+
0
-

Tohle asi bude nejlepší

try {
   	funkce1();
   	funkce2(); 	//pokud nastane chyba vyhodí výjimku (throw new InvalidStateException("bla bla");)
   	funkce3();
   	$this->flashMessage('Objednávka byla uložena');
   	$this->redirect('Default:default');
} catch  (InvalidStateException $e) {
	$this->flashMessage($e->message);
	//nebo ještě líp:
	$form->addError($e->message); 	//přidá chybu formuláři
}

Jakmile catch zachytí výjimku, další kód v bloku try se už neprovádí (žadný flash, žádný redirect)

Velmi důležité je aby se nepoužíval obecný typ ‚Exception‘, protože pak by catch zachytil i výjimky týkající se změn stavu nette aplikace, konkrétně v tomto případě RedirectException, která se obsluhuje až v aplikaci (Application), lepší je využít konkrétních typů už do nette vložených, nebo si napsat vlastního potomka třídy Exception, nebo lze potom výjimku znovu vyhodit v bloku catch (throw $e;), aby ji obstaral „nadřazený kód“