processException() v PRODUCTION modu s následným redirectem zlobí
- Petr Tvaroha
- Člen | 25
Učím se pracovat s laděnkou a nemohu přijít na jednu věc. Zachytím výjimku a zpracuju jí pomocí processException($e), kdy si chci pouze zalogovat a emailovat chybu a pak chci pokračovat dál. Ale když pak volám $presenter->redirect(‚someview‘), tak dostanu další výjimku, která způsobí, že se zobrazí prázdná stránka, místo toho, aby skript pokračoval dál. Když nevolám redirect, tak to proběhne dle mých požadavků.
Je to vlastnost, nebo chyba?
Podrobněji:
- odešlu formulář
- data zpracuji v formSubmitted(), kde uložím data do DB a pak si chci poslat data mailem, ale nechci, aby uživatel zaregistroval, pokud by náhodou došlo k chybě při odeslání mailu:
<?php
//jsem ve třídě např. MyPresenter, mode mam nastaveny na PRODUCTION
public function formSubmitted()
{
// zpracuju data, ulozim do DB
...
// chci je poslat v mailu, ale dojde k chybe pri odesilani
try {
$mail = new Mail();
...
$mail->send();
} catch(Exception $e) {
Debug::processException($e); // chci zalogovat do souboru a poslat si chybu emailem, což obojí proběhne v pořádku
)
// a ted chci normálně pokračovat, ale když uvedu ...
$this->redirect('view2'); // tak dostanu další výjimku... (níže)
}
/* druhá výjimka:
PHP Fatal error: Uncaught exception 'InvalidStateException' with message
'Cannot set HTTP code after HTTP headers have been sent
(output started at C:\Web\www\test\libs\Nette\Debug.templates\bluescreen.phtml:355).'
in C:\Web\www\test\libs\Nette\Web\HttpResponse.php:80
*/
?>
Předem díky za odpověď.
PHP 5.2.6 na Apache 2.0.63 na Win7, Nette 0.9.2 rev. b9fd602
Doplnění:
Právě jsem si stáhnul poslední dev verzi Nette, chová se stejně. Zajímavé je, že když volám v bootstrap.php:
<?php
Debug::enable(Debug::PRODUCTION, NULL, 'webmaster@example.com');
?>
chová se to tak, jak jsem popsal výše.
Pokud však přidám:
<?php
Environment::setMode('production',TRUE);
?>
Tak se mi zobrazí Error view: 500 Internal Server Error.
Editoval Petr Tvaroha (13. 12. 2009 14:32)
- Petr Tvaroha
- Člen | 25
Jo, jasně, že se tam něco posílá na výstup. Ale posílá to právě ta funkce processException(), která by ale neměla. Proto mi přijde, že v ní někde bude možná nějaká chybka.
- Petr Tvaroha
- Člen | 25
Tak jsem zatím zjistil, že to je problém s output bufferingem, kdy se logují detaily výjimky do html souboru ve funkci Debug::processException().
Když zakomentuju…
ob_start(array(__CLASS__, '_writeFile'),1); // line 612, file Debug.php
self::_paintBlueScreen($exception); // line 613
ob_end_flush(); // line 614
…tak to proběhne v pořádku.
Pro mě to tedy znamená, buď to nechat zakomentované a přijít o detaily výjimky, nebo si napsat vlastní funkci logException().
- Petr Tvaroha
- Člen | 25
Díky moc! To mi dost pomůže.
Jenom ale potom nerozumím tomu, proč tedy
Debug::processException()
něco vůbec posílá na výstup, když
mám $outputAllowed = FALSE
. V popisu parametru je
@param bool is writing to standard output buffer allowed?
a já
to tedy chápu tak, že by neměla funkce posílat na výstup vůbec nic, tiše
provést vše potřebné (log, mail, …) a skončit.
Nebo to chápu špatně?