Ublaboo\api-router a ošetření výjimek
- forkman
- Člen | 72
Ahoj, api-router jako takový mi funguje, ale potřeboval bych mít ošetřené i výjimky (hlavně BadRequest) a posílat je taky jako JSON a ne jako klasický HTML error. Nedokážu toho ale docílit.
Nette moc neovládám a nedokážu ErrorPresenter v API modulu donutit, aby posílal JSON response. Vždycky dostanu jen klasický Error500 a logu je Nette\Application\AbortException, který následuje po JsonResponse. Použil jsem kód ErrorPresenteru, který je v ukázkovém projektu na Githubu.
<?php
declare(strict_types=1);
namespace ResourcesModule;
use App\Http\ApiResponse;
use Nette\Application\IResponse;
use Nette\Application\Request;
final class Error4xxPresenter extends AbstractController
{
public function run(Request $request): IResponse
{
$exception = $request->getParameter('exception');
/**
* @todo Log exception
*/
return $this->sendJson($this->apiResponseFormatter->formatException($exception));
}
}
Nemáte někdo tip jak na to?
- Pavel Janda
- Člen | 977
Jsi si jistý, že se ti tento presenter spouští? V závislosti na tom potom můžeme hledat dál 👍
- forkman
- Člen | 72
Ano, jsem si jistý, že se ten presenter spouští (dal jsem si tam echo :-D ). Ale taky se přiznám, že přesně nevím, co dělá. Předpokládal jsem, že když vyhodím výjimku, zejména BadRequest, kterou neošetřím, chytí ji ErrorPresenter a pošle JSON response se správným obsahem a hlavičkou. Můžu si to výjimku samozřejmě ošetřit a poslat si tam ten JSON response sám, ale pak mám samozřejmě HTTP status 200 a to já nechci.
- Pavel Janda
- Člen | 977
@forkman Nevím, jak přesně vypadá tvá appka, ale můžeš si
například v nějakém předkovi svých presenterů přepsat metodu sendJson
tak, aby posílal tvůj vlastní JsonResponse, která bude umět posílat
i status kód. Příklad:
Místo:
class UI\Presenter
public function sendJson($data): void
{
$this->sendResponse(new Responses\JsonResponse($data));
}
->
abstract class ApiPresenter
public function sendJson($data, int $code): void
{
$this->sendResponse(new ApiJsonResponse($data, null, $code));
}
final class ApiJsonResponse
public function __construct(private $payload, private string $contentType = null, private int $code = 200)
public function send(IRequest $httpRequest, IResponse $httpResponse): void
{
$httpResponse->setContentType($this->contentType, 'utf-8');
$httpResponse->setCode($this->code);
echo Json::encode($this->payload);
}
Editoval Pavel Janda (3. 11. 2020 14:51)