ErrorPresenter v modulech
- d@rkWolf
- Člen | 167
Zdravím,
poradil by mi někdo, jak dostat Error Presentery do jednotlivých modulů? Mám
základ ze sandboxu Nette 2.4 a nedaří se mi dohledat nic aktuálního, jak
to vyřešit. Teď mám ten výchozí ErrorPresenter ze Sandboxu mimo
moduly(Admin/Front), ale potřeboval bych to nějak nasměrovat do modulů tak,
abych mohl mít šablony Errorů oddělené zvlášť pro Admin a zvlášť pro
Front(nebo eventuelně i něco jiného), hlavně aby 4xx errory využívaly
výchozí layout.latte danného modulu a zároveň, abych mohl ty
ErrorPresentery zdědit z basePresenterů daného modulu(budu tam potřebovat
překlady kdyby/translation, nějaké komponenty typu hledání…).
Při hledání jsem narazil na zjistění a nasměrování pomocí:
<?php
if (Strings::startsWith($request->presenterName, 'Front:')) {
$this->forward(':Front:Error:', [
'exception' => $exception,
'request' => $request,
]);
}
?>
To mi přišlo nadějné, ale ukázalo se, že $request->presenterName vrací „Error“, nikoliv něco jako „Front:NeexistujiciCesta“, takže z toho ten routovaný modul nezjistím.
Jak zjistit modul a přesměrovat to? Nebo je nějaké jiné řešení, jak docílit toho co potřebuju?
- David Matějka
- Moderator | 6445
ahoj, odkud si vzal ten request? je potřeba jej vzít z parametrů
aktuálního requestu přes $this->getParameter('request')
, resp
si jej vyžádat v argumentech action metody
- Kamil Valenta
- Člen | 822
V ErrorPresenteru si vyžádej z DI router a HttpRequest, z requestu si routerem matchni modul a na ten forwardni.
- d@rkWolf
- Člen | 167
@DavidMatějka ten request v tom ErrorPresenter sandboxu už byl, je tam tato funkce:
<?php
public function run(Nette\Application\Request $request): Nette\Application\IResponse
{
$exception = $request->getParameter('exception');
if ($exception instanceof Nette\Application\BadRequestException) {
[$module, , $sep] = Nette\Application\Helpers::splitName($request->getPresenterName());
return new Responses\ForwardResponse($request->setPresenterName($module . $sep . 'Error4xx'));
}
$this->logger->log($exception, ILogger::EXCEPTION);
return new Responses\CallbackResponse(function (Http\IRequest $httpRequest, Http\IResponse $httpResponse): void {
if (preg_match('#^text/html(?:;|$)#', $httpResponse->getHeader('Content-Type'))) {
require __DIR__ . '/templates/Error/500.phtml';
}
});
}
?>
Editoval d@rkWolf (20. 5. 2019 16:12)
- Matey
- Člen | 142
Ahoj, ja som to vyriešil tak že som si z $requestu ktorý prijíma ErrorPresenter vytiahol request (ten pôvodný na ktorom došlo k chybe). Vypadá to takto:
public function run(Application\Request $request): Application\IResponse
{
$e = $request->getParameter('exception');
if ($e instanceof Application\BadRequestException) {
// $this->logger->log("HTTP code {$e->getCode()}: {$e->getMessage()} in {$e->getFile()}:{$e->getLine()}", 'access');
$presenterName = $request->getParameter('request') ? $request->getParameter('request')->getPresenterName() : $request->getPresenterName();
[$module, , $sep] = Application\Helpers::splitName($presenterName);
$errorPresenter = $module . $sep . 'Error4xx';
try {
$this->presenterFactory->createPresenter($errorPresenter);
} catch (Application\InvalidPresenterException $exception) {
return new Application\Responses\ForwardResponse($request->setPresenterName('Error:Error4xx'));
}
return new Application\Responses\ForwardResponse($request->setPresenterName($errorPresenter));
}
$this->logger->log($e, ILogger::EXCEPTION);
return new Application\Responses\CallbackResponse(function (Http\IRequest $httpRequest, Http\IResponse $httpResponse): void {
if (preg_match('#^text/html(?:;|$)#', $httpResponse->getHeader('Content-Type'))) {
require __DIR__ . '/templates/Error/500.phtml';
}
});
}
- d@rkWolf
- Člen | 167
@Matey jo něco takového jsem zrovna zkoušel, jen sem si nebyl jistej, že je vhodný postup
Zdá se, že 404 se zobrazuje správně uvnitř šablon.
Ovšem 403ka v adminu se nechytá(potřebuju to donutit vyhazovat tu error page pokud přihlášený uživatel nemá práva), šablona tam je, jak to chápu, tak by to mělo na základě kódu vybrat tu 403 šablonu, místo toho mi to ale furt vyhazuje Nette\Application\ForbiddenRequestException #403 z Tracy – i s „catchException: true“.
Výjimku vyhazuju normálně ve f-ci checkRequirements a do toho ErrorPresenteru to neproleze.
<?php
if (!$this->user->isLoggedIn()) {
...
} elseif (!$this->user->isAllowed($resource)) {
throw new Nette\Application\ForbiddenRequestException;
}
?>
- Matey
- Člen | 142
Odskúšal som a u mňa je to ok. S catchException: true dostávam správnu 403 šablónu zo správneho modulu. Máš pre každý modul Error4xxPresenter? Ja to mám takto:
Error:ErrorPresenter implements IPresenter - hlavný error presenter
Error:Error4xxPresenter extends Nette\Application\UI\Presenter + šablóny
Front:Error4xxPresenter extends BaseFrontPresenter + šablóny
Admin:Error4xxPresenter extends BaseAdminPresenter + šablóny
- d@rkWolf
- Člen | 167
Mám to stejně, jen jsem úplně ten výchozí Error4xx(2.řádek), nastavil jsem to tak, že to vždycky spadne buď do admin, nebo front ten Error4xx, nevím, zda na to nemůže mít vliv, že mám ten admin načítanej ajaxem, nicméně nefunguje to ani, když si adresu té nepřístupné stránky zapíšu do adresy, ani když ju vyvolám přes ajaxové tlač. v menu, vždycky skončím na Tracy, vůbec nevím, kde ten problém hledat.
- Kamil Valenta
- Člen | 822
No ale to už řešíš jinou otázku, ne? V debug mode končí exceptiony v tracy. Buď si vypni debug, nebo si do neonu dej catchExceptions: true
- d@rkWolf
- Člen | 167
Právě, že jde o to, že catchExceptions: true v Neonu mám, když zkusím neexistující stránku pro 404 tak se správně objeví v obsahu, ať už adminu, nebo front-endu, ale 403 když kliknu v adminu na odkaz, do kterého nemám práva, se mi ukáže v Tracy, pořád, ať je v catchException cokoliv(mazat cache jsem zkoušel). Při vypnutém debugu se Tracy neukáže, ale místo toho se mi v Ajax dotazu zobrazí 500 a do log se uloží Tracy s tím samým, co se zobrazuje když mám ten debug zapnutý.