Dynamické vypnutí Tracy a Error Prezentéry

DefenestrationPraha
Člen | 120
+
0
-

Mám situaci, kdy mám spuštěnou Tracy v developerském režimu, ale za nějakých okolností chci ten developerský režim (už po vzniku kontejneru) vypnout a přehodit na produkční. Zavolám tedy

$configurator->setDebugMode(false);

Má to jedinou chybu. Tracy v tomto případě i nadále „žere“ výjimky a aplikace nemá nastavené žádné error prezentéry. Ty se nastaví (nebo nenastaví a jsou null) jen při inicializaci aplikace, a pak už se nikdy neupraví.

Dokážu si s tím asi poradit nějak ručně přes kontejner, ale moc mě to netěší. Nešlo by to nějak opravit přímo v Nette?

Pavel Kravčík
Člen | 1195
+
0
-

Nepomůže:

application:
	catchExceptions: true|false
DefenestrationPraha
Člen | 120
+
0
-

Moje momentální řešení je toto. Pošlu si do metody příslušné parametry (instanci konfigurátoru, instanci kontejneru a jména error prezentérů, které chci nastavit), a zavolám následující kód:


    public const CONFIGURATOR = 'configurator';
    public const CONTAINER = 'container';

    public const ERROR_PRESENTERS = 'error_presenters';
    public const ERROR_ANY = 'error_any';
    public const ERROR_4xx = 'error_4xx';
    public const ERROR_5xx = 'error_5xx';

    private static function disableDebugger(array $params): void
    {
        $configurator = $params[self::CONFIGURATOR];
        $container    = $params[self::CONTAINER];
        $configurator->setDebugMode(false);
        $error_presenters = $params[self::ERROR_PRESENTERS] ?? [];
        /* If we disable Tracy, we need to renew the functionality of Error Presenters */
        if (!empty($error_presenters)) {
            $application  = $container->getByType(Application::class);
            if (!is_null($application)) {
                foreach ($error_presenters as $key => $presenter) {
                    if (($key === self::ERROR_5xx) && property_exists($application, 'errorPresenter')) {
                        $application->errorPresenter = $presenter;
                    }
                    if (($key === self::ERROR_ANY) && property_exists($application, 'errorPresenter')) {
                        $application->errorPresenter = $presenter;
                    }
                    if (($key === self::ERROR_4xx) && property_exists($application, 'error4xxPresenter')) {
                        $application->error4xxPresenter = $presenter;
                    }
                }
            }
        }
    }

Editoval DefenestrationPraha (24. 4. 17:53)

Marek Bartoš
Nette Blogger | 1263
+
0
-

Proč to děláš?

Build containeru je na debug módu závislý a mnoho rozšíření na to při nastavení služeb spoléhá, takže po buildu debug mód přepnout nejde. Maximálně můžeš přenastavit služby které to dovolují, aby se chovaly stejně jako s vypnutým debug módem.

Editoval Marek Bartoš (24. 4. 18:27)

DefenestrationPraha
Člen | 120
+
0
-

Marek Bartoš napsal(a):

Proč to děláš?

¯\_(ツ)_/¯

Nevyhovuje mi nastavování debug módu v konfiguračních souborech ani natvrdo v kódu, no. U některých prezentérů bych jej chtěl, u jiných ne – zejména ne u těch, které se starají o nějaké strojově čitelné API a lidé na ně vůbec nelezou.

Současná podoba Nette to sice má celkem chytře, ale rozhodnutí jen podle IP adresy nebo cookie nemusí každému vyhovovat… Nemluvě o tom, že pak musíš zadrátovávat svoje IP adresy do zdrojáku. Sám jsem si to udělal tak, že se IP adresy pro povolenou Tracy ukládají do databáze jako každé jiné nastavení a načítají se dynamicky, pak to ovšem nemusí být v bootloaderu.

Build containeru je na debug módu závislý, takže po buildu debug mód přepnout nejde. Maximálně můžeš přenastavit služby které to dovolují, aby se chovaly stejně jako s vypnutým debug módem.

To mě upřímně nenapadlo, dvojnásob ne proto, že nikde v dokumentaci bootloaderu není psáno, že setDebugMode() by měla jiné efekty před konstrukcí kontejneru vs. potom.

Naopak autory Nette asi nenapadlo, že se v tom bude chtít někdo takhle pitvat, tomu rozumím.

Editoval DefenestrationPraha (24. 4. 18:32)

Marek Bartoš
Nette Blogger | 1263
+
0
-

prezentérů bych jej chtěl, u jiných ne – zejména ne u těch, které se starají o nějaké strojově čitelné API a lidé na ně vůbec nelezou

Proč je tam debug mód problém?

rozhodnutí jen podle IP adresy nebo cookie nemusí každému vyhovovat

Víš, že metoda setDebugMode() přijímá boolean? Můžeš si to nastavit jak chceš. Třeba na kliknutí v administraci

To mě upřímně nenapadlo, dvojnásob ne proto, že nikde v dokumentaci bootloaderu není psáno, že setDebugMode() by měla jiné efekty před konstrukcí kontejneru vs. potom.

Primární funkce containeru je sestavit DI container.

Editoval Marek Bartoš (24. 4. 19:02)

DefenestrationPraha
Člen | 120
+
0
-

Marek Bartoš napsal(a):

rozhodnutí jen podle IP adresy nebo cookie nemusí každému vyhovovat

Víš, že metoda setDebugMode() přijímá boolean? Můžeš si to nastavit jak chceš. Třeba na kliknutí v administraci

To mě upřímně nenapadlo, dvojnásob ne proto, že nikde v dokumentaci bootloaderu není psáno, že setDebugMode() by měla jiné efekty před konstrukcí kontejneru vs. potom.

Primární funkce containeru je sestavit DI container.

Konfigurátoru, ne kontejneru, ale to je drobnost…

Vím, že metoda setDebugMode přijímá boolean. Nějak jsem si to naprogramoval, ale prostě její chování se liší předtím, než vyrobíš pomocí konfigurátoru kontejner a potom.

Před chvílí jsi mi vysvětlil proč – podoba kontejneru se liší podle toho, zda konfigurátor měl zapnutý debug mode nebo ne. To ale znamená, že jednou vypnutý debug mód už nejde „úplně zapnout“ a jednou zapnutý debug mód už nejde „úplně vypnout“, jakmile je kontejner sestaven.

Možná to každý nechápe, já jsem to až dosud taky nechápal. V dokumentaci se to nerozebírá. Proto bude užitečné, aby byl nějaký záznam i tady ve fóru.

Sám nevím, co všechno dokážu „vypnout“, když chci deaktivovat debug mód programátorsky poté, co byl zapnut, ale co se nastavení error prezentérů týče, mám to řešení viz výše.

Marek Bartoš
Nette Blogger | 1263
+
+1
-

Konfigurátoru, ne kontejneru, ale to je drobnost

Oops, brain fart

Vím, že metoda setDebugMode přijímá boolean. Nějak jsem si to naprogramoval, ale prostě její chování se liší předtím, než vyrobíš pomocí konfigurátoru kontejner a potom.

Pointa je, že neexistuje důvod proč měnit nastavení debug módu po vytvoření DIC, když si o tom můžeš dostatečně flexibilně rozhodnout už před vytvořením.

DefenestrationPraha
Člen | 120
+
0
-

Marek Bartoš napsal(a):

Konfigurátoru, ne kontejneru, ale to je drobnost

Oops, brain fart

Vím, že metoda setDebugMode přijímá boolean. Nějak jsem si to naprogramoval, ale prostě její chování se liší předtím, než vyrobíš pomocí konfigurátoru kontejner a potom.

Pointa je, že neexistuje důvod proč měnit nastavení debug módu po vytvoření DIC, když si o tom můžeš dostatečně flexibilně rozhodnout už před vytvořením.

To je celkem silné tvrzení.

Hodnota, podle které se chci rozhodnout, je zapsána v databázi. K jejímu načtení potřebuji ideálně prolézt skrze databázovou fasádu na Nette Database Explorer. K tomu ale potřebuju kontejner, ne? Stejně tak, chci-li se rozhodnout podle aktuálního requestu – kam míří, co obsahuje.

Nebo se musím vykašlat na rozhodování podle parametrů v databázi, což zas tak flexibilní není. Musím to zadrátovat do NEONu nebo Bootstrap.php.

Marek Bartoš
Nette Blogger | 1263
+
0
-

Už jsem tě odkázal na jednoduché řešení, které potřebuje jen cookie a soubor na disku, není třeba při spouštění aplikace pro ověření debug módu dělat dotaz do databáze.
Při zapínání debug módu pro aktuálního uživatele už máš container dostupný, a tak celé řešení můžeš klidně udělat závislé i na databázi.

A pořád jsi nenapsal, proč chceš o debug módu rozhodovat podle aktuálního requestu.

DefenestrationPraha
Člen | 120
+
0
-

Marek Bartoš napsal(a):

Už jsem tě odkázal na jednoduché řešení, které potřebuje jen cookie a soubor na disku, není třeba při spouštění aplikace pro ověření debug módu dělat dotaz do databáze.

Pro tebe jako pro autora je to asi jednoduché, já musím říci, že se v tom vůbec nevyznám, bohužel.

Při zapínání debug módu pro aktuálního uživatele už máš container dostupný, a tak celé řešení můžeš klidně udělat závislé i na databázi.

Zapneš-li debug mód až poté, co máš kontejner dostupný, nemusí to vypadat dobře. Například se mi nepodařilo udělat celou tracy, nevím proč. To jsem tady ani řešit nechtěl.

A pořád jsi nenapsal, proč chceš o debug módu rozhodovat podle aktuálního requestu.

Psal jsem už předtím, že na některých prezentérech ten debug mód mít chci podle potřeby, na některých jej nechci mít víceméně nikdy, jednak kvůli výkonu, jednak kvůli tomu, aby pak v nějakých chybových datech nechodily masivní dumpy z Tracy atd.

David Grudl
Nette Core | 8218
+
+1
-

Debug mod vlastně říká, jestli u prohlížeče sedí programátor nebo ne. Podle toho se pak sestavuje a konfiguruje aplikace. Pokud debug mód později změníš (ale dává to smysl jen z nedebug na debug, ne obráceně), je asi nejlepší vygenerovat nový kontejner.

Psal jsem už předtím, že na některých prezentérech ten debug mód mít chci podle potřeby,

Tady bude asi nějaké nepochopení, protože programátor buď u prohlížeče sedí nebo ne, nezávisle na presenteru. Řekl bych, že k tomu, čeho se snažíš dosáhnout, není přepínání debug modu vhodný postup.

DefenestrationPraha
Člen | 120
+
-3
-

David Grudl napsal(a):

Debug mod vlastně říká, jestli u prohlížeče sedí programátor nebo ne. Podle toho se pak sestavuje a konfiguruje aplikace. Pokud debug mód později změníš (ale dává to smysl jen z nedebug na debug, ne obráceně), je asi nejlepší vygenerovat nový kontejner.

Psal jsem už předtím, že na některých prezentérech ten debug mód mít chci podle potřeby,

Tady bude asi nějaké nepochopení, protože programátor buď u prohlížeče sedí nebo ne, nezávisle na presenteru. Řekl bych, že k tomu, čeho se snažíš dosáhnout, není přepínání debug modu vhodný postup.

Snažím se dosáhnout toho, aby se do některých prezentérů nemíchal debug mód nikdy, i když u nich náhodou zrovna sedím já a testuju jejich fungování v ostrém provozu tím, že si jakoby hraju na volajícího vzdáleného klienta apod.

To je prostě odlišnost modelů, které nosíme v hlavě. Ty jako autor jsi pojal debug mód tak, jak říkáš: „jestli u prohlížeče sedí programátor nebo ne“.

Já to vnímám jinak, mně vyhovuje si jej aktivovat a deaktivovat i na základě jiné logiky, než jen toho, zda sedím u prohlížeče nebo ne.

Respektuju samozřejmě to, že jako autor tohoto mocného balíčku rozhoduješ o jeho vnitřní logice ty. Jenom to holt musím nějak obejít, protože zase nechci přizpůsobovat svůj mentální model tomuto principu, který mi nesedí.

David Grudl
Nette Core | 8218
+
+1
-

Snažím se dosáhnout toho, aby se do některých prezentérů nemíchal debug mód nikdy,

Zkus popsat konkrétně jako dítěti, čeho se snažíš dosáhnout. Já upřímně netuším co si představit pod mícháním debug módu v presenterech.

(Jediný vliv debug modu na presentery je ten, že ovlivňuje přístup k neplatným odkazům, ale o tom asi řeč není)

DefenestrationPraha
Člen | 120
+
+1
-

David Grudl napsal(a):

Snažím se dosáhnout toho, aby se do některých prezentérů nemíchal debug mód nikdy,

Zkus popsat konkrétně jako dítěti, čeho se snažíš dosáhnout. Já upřímně netuším co si představit pod mícháním debug módu v presenterech.

(Jediný vliv debug modu na presentery je ten, že ovlivňuje chování u neplatných odkazů, ale o tom asi řeč není)

Možná nerozumím přesně tomu, jak souvisí debug mód a Tracy. Jde mi zejména o Tracy.

Na některých prezentérech rozhodně nechci mít Tracy, nikdy, a chci, aby na nich vždycky fungovalo ošetření výjimek pomocí Error Prezentérů.

Na jiných prezentérech chci ale Tracy mít v závislosti na tom, co se nachází v nastavení v databázi, a nevadí mi, že svojí existencí sežere Error Prezentéry.

Tohoto se mi zatím podařilo dosáhnout jen tak, že nejdřív debug mód zapnu pro vytvoření kontejneru vždycky, a pak si jej případně vypnu a přenastavím Error Prezentéry zase zpět tím kódem, který jsem nasdílel. Žádný jiný způsob mi zatím nefungoval, respektive z toho vznikaly podivné chyby, neúplná Tracy atd.

Mám ale z vás obou dojem, že se mi snažíte naznačit, že samotná myšlenka si tu Tracy zapínat a vypínat podle prezentéru je bizarní a absurdní. Mně to tak nepřijde, ale na takovou debatu už bych se necítil.

jeremy
Člen | 54
+
+1
-

Samotny debug mod je bud zaply nebo vyply pro vsechny presentery. Tracy se da schovat v tvym pripade pomoci Tracy\Debugger::$showBar = true|false (Taky to je mozny pomoci neon konfigurace). To stejne ale asi nevyresi tvuj problem, alespon ne uplne. Ceho se snazis dosahnout je opravdu celkem absurdni, jak jsi sam napsal.

DefenestrationPraha
Člen | 120
+
+1
-

No tak já napíšu jeden detail, který mě předtím nenapadlo napsat, aby bylo patrné, proč to tak absurdní není.

Nette obecně má zadrátováno „localhost = vývojový režim“. To na 99 procent platí, ale bohužel nikoliv v mém případě. Mně při tom vývoji na tom localhostu běží taky nějaké jiné procesy, Python skripty nebo jiné weby komunikující ven pomocí curlu, které se taky podle různých pravidel snaží přistupovat na ten vyvíjený web, protože ten vyvíjený systém je na to částečně dělaný a v ostrém provozu tam podobné komunikace budou. On prostě není určen jen na přístup z prohlížeče, ale i jako nějaké robotické rozhraní pro jiné stroje, kde ani neposílá HTML, ale JSON.

Z pohledu Nette je taková místní komunikace samozřejmě „přístup z localhostu jako přístup z localhostu“, takže i v rámci této komunikace mezi dvěma stroji, které se jako vývojář aktivně neúčastním, tam Nette zapne debug mód, Tracy atd. Což má za následek, že cokoliv selže, tak se poměrně blbě ladí. Místo jednoduché chybové zprávy, která je zamýšlená pro ostrý provoz, dojde na ten volající skript třeba 400 kB debugovací zpráva, která by byla v prohlížeči živému člověku užitečná, ale jejíž dump na disk moc užitečný není.

Proto to chci mít uděláno tak, aby i v rámci komunikace localhost-to-localhost určité prezentéry měly prostě toto vypnuté a komunikovaly stejně jako v produkci – ty prezentéry, které se baví hlavně s těmi jinými procesy. Ale nechci samozřejmě sestřelit debugování celkově, protože zároveň ladím ten web, takže na těch prezentérech, které jsou určeny pro lidi (ne pro stroje) chci mít debugovací režim pro svoji potřebu.

Editoval DefenestrationPraha (24. 4. 21:14)

David Grudl
Nette Core | 8218
+
+1
-

Řekl bych, že to co hledáš, je aktivace debug režimu pomocí cookie https://doc.nette.org/…on/bootstrap#…

DefenestrationPraha
Člen | 120
+
0
-

David Grudl napsal(a):

Řekl bych, že to co hledáš, je aktivace debug režimu pomocí cookie https://doc.nette.org/…on/bootstrap#…

Hmm, to je chytré. To by opravdu fungovalo. Díky.

DefenestrationPraha
Člen | 120
+
0
-

David Grudl napsal(a):

Řekl bych, že to co hledáš, je aktivace debug režimu pomocí cookie https://doc.nette.org/…on/bootstrap#…

Hele, když už tě tady máme: čím vším se prosím ten debug mód liší od produkčního módu?

Chápu-li dobře, implicitně se při něm aktivuje Tracy (a deaktivují Error Prezentéry, protože chyby sbírá a zobrazuje Tracy) a také se nějak jinak řeší odkazy, ale jsou tam i nějaké další významné rozdíly (pod kapotou či viditelné?)

Editoval DefenestrationPraha (24. 4. 21:29)

David Grudl
Nette Core | 8218
+
+1
-

@DefenestrationPraha ještě aktualizuje cache při změně šablon nebo konfigurace DI kontejneru, to bude asi všechno