Mám zajímavý problém s Latte 3 a RenderToString

grovik
Člen | 90
+
0
-

Vyřešeno!!
Přišel jsem na to.
Problém dělají ty sendResponse(). Pokud jsem to celé předělal a dělám jedno sendResponse na konci je to OK.
Asi nechávám, vyřešil jsem tady i nikde v návodu nezmíněných postup randerToString s proměnnou obsahujíc šablonu a ne odkaz na šablonu asi by to bylo dobré dát to někam do dokumentece.

Mám tuhle metodu:

public function actionPreview(): jsonResponse
    {
        if ($this->getHttpRequest()->getMethod() !== 'POST') {
            $this->error('Neplatný požad    avek.', 405);
        }
        $payload = $this->getHttpRequest()->getPost();
        bdump($payload);
        $code =  $payload['code'] ?? '';
       // $varsJson = !empty($payload['variables']) ? null  : $payload['variables'];
        $inputChannels = !isset($payload['inputChannels']) ? [] : $payload['inputChannels'];
        $outputChannels = !isset($payload['outputChannels']) ? [] : $payload['outputChannels'];

        // Zkus dekódovat JSON proměnných

        if (!empty($payload['variables'])) {
            $vars = json_decode($payload['variables'], true);
            bdump($vars);
            if (json_last_error() !== JSON_ERROR_NONE) {
                bdump(json_last_error());

                $this->sendResponse(new JsonResponse([

                    'snippets' => [
                        'lattePreview' => null,
                        'error' => '<div class="alert alert-warning">Neplatné proměnné (JSON): ' . htmlspecialchars(json_last_error_msg()) . '</div>'
                    ]
                ], 'application/json'));
            }
        }
        else
        {
            $vars = [];
        }

        try {
            $latte = new Engine();
            $latte->setLoader(new StringLoader());

            $html = $latte->renderToString($code, $vars);
            $html = mb_convert_encoding($html, 'UTF-8', 'UTF-8');

            $json = new JsonResponse([ 'snippets' => [
                'lattePreview' => $html,
                'error' => '<div class="alert alert-success"><strong>Vše OK</strong> ' . '</div>'
            ]]);
            $this->sendResponse($json);


        } catch (\Throwable $e) {

            $json = new JsonResponse([ 'snippets' => [
                'lattePreview' => null,
                'error' => '<div class="alert alert-danger"><strong>Chyba:</strong> ' . htmlspecialchars($e->getMessage()) . '</div>'
            ]]);
            $this->sendResponse($json);
        }

    }

Problém který nastává:
Výsledek vždy spadne to CATCH a to i v případě, že se vše správně vyrenderuje.
Pokud Try/Catch vyhodím je to OK a dostanu korektní výsledek.
Problém který s tím mám je to, že pokud tam nebudu mít Try Catch tak narazím na to, že mi to spadne když na vstupu bude nějaká bota.

Problém je že když je vše v pořádku spadne to do Catch chyba je prázdná (prostě nic), ale něco vyvolalo něco co je zachytitelné. A já naprosto netuším co.
Když Try catch vyhodím tak to jak jsem psal funguje. Výsledek se vyrenderuje a vše je ok.
Sorry je to takové neučesané, ale už s tím drbu půl dne a nemůžu na to přijít. Napadlo mě, že by mohla být chyba někde v latte, že prostě někde tam je utopená návratová chyba… ale prostě už nevím. :D

Editoval grovik (16. 9. 15:56)

David Grudl
Nette Core | 8284
+
+2
-

Dej $this->sendResponse($json); za try/catch

grovik
Člen | 90
+
0
-

David Grudl napsal(a):

Dej $this->sendResponse($json); za try/catch

jj Přesně tak to pomohlo, ale i tak mi to přijde trochu divné. Proč? (jo ptám se jako moje šestiletá dcera) :D

David Grudl
Nette Core | 8284
+
+2
-

Protože to vyhazuje AbortException

grovik
Člen | 90
+
0
-

David Grudl napsal(a):

Protože to vyhazuje AbortException

Děkuji mnohokrát za osvětlení…

Marek Bartoš
Nette Blogger | 1311
+
0
-

Používej try jen na ty řádky kódu, od kterých výjimku očekáváš.
Odchytávej v catch jen tu výjimku, kterou očekáváš, Throwable je obecné.
Vytvářej nové Exception třídy reprezentující konkrétní problémy v aplikaci. Vynuť si jejich zpracování přes PHPStan.
Vyhneš se tak řadě problémů.

V http requestu přijímáš kód šablony – měl bys zvážit v Latte zapnout sandbox mód, kvůli bezpečnosti. {var $rip = Nette\Utils\Filesystem::delete(getcwd())}