Preskočiť na obsah

Spracovanie chýb ​

ApiPresenter chybové odpovede nikdy nevytvára sám. Zavolá službu ErrorHandlerInterface, zvyčajne DefaultErrorHandler.

Rozhranie a predvolené odpovede ​

MetódaVolá sa, keďDefaultErrorHandler odpovie
handle(Throwable, array $params)handle() vyhodil výnimku500 Internal server error, loguje do Tracy
handleInputParams(array $errors)parametre sú neplatné400 wrong input
handleSchema(array $errors, array $params)kontrola výstupu zlyhala500 Internal server error, loguje do Tracy
handleAuthorization(ApiAuthorizationInterface, array $params)authorized() je false401 s getErrorMessage()
handleAuthorizationException(Throwable, array $params)authorized() vyhodil výnimku500 s textom výnimky

Všetky vracajú JsonApiResponse so status: error a message.

Detaily chýb ​

DefaultErrorHandler(ConfiguratorInterface) pridá detail, keď je showErrorDetail() konfigurátora true: text výnimky pre 500, chyby jednotlivých polí pre 400, chyby schémy pre pokazený výstup.

json
{"status":"error","message":"Internal server error","detail":"Database connection refused"}

Ktorý konfigurátor použiť, opisujú Výstupy. V produkcii majú byť detaily vypnuté.

Vlastný error handler ​

DefaultErrorHandler je final, takže ho obaľte. Príklad logovania zmení jednu výnimku na 503 a zvyšok nechá predvolenému:

php
<?php

declare(strict_types=1);

namespace App;

use Throwable;
use Tomaj\NetteApi\Authorization\ApiAuthorizationInterface;
use Tomaj\NetteApi\Error\ErrorHandlerInterface;
use Tomaj\NetteApi\Response\JsonApiResponse;

/**
 * Answers MaintenanceException with 503 and leaves everything else to DefaultErrorHandler.
 */
final class AppErrorHandler implements ErrorHandlerInterface
{
    public function __construct(private ErrorHandlerInterface $inner)
    {
    }

    public function handle(Throwable $exception, array $params): JsonApiResponse
    {
        if ($exception instanceof MaintenanceException) {
            return new JsonApiResponse(503, ['status' => 'error', 'message' => 'Down for maintenance, try again later']);
        }
        return $this->inner->handle($exception, $params);
    }

    public function handleInputParams(array $errors): JsonApiResponse
    {
        return $this->inner->handleInputParams($errors);
    }

    public function handleSchema(array $errors, array $params): JsonApiResponse
    {
        return $this->inner->handleSchema($errors, $params);
    }

    public function handleAuthorization(ApiAuthorizationInterface $auth, array $params): JsonApiResponse
    {
        return $this->inner->handleAuthorization($auth, $params);
    }

    public function handleAuthorizationException(Throwable $exception, array $params): JsonApiResponse
    {
        return $this->inner->handleAuthorizationException($exception, $params);
    }
}
yaml
services:
	defaultErrorHandler:
		factory: Tomaj\NetteApi\Error\DefaultErrorHandler
		autowired: false
	- App\AppErrorHandler(@defaultErrorHandler)

autowired: false zabezpečí, že na autowiring ostane jediný ErrorHandlerInterface.

Časté otázky ​

Prečo produkcia vráti 400 bez toho, aby povedala, ktoré pole je zlé? ​

DefaultErrorHandler skryje detail pre všetky kódy, keď je showErrorDetail() false, vrátane 400. DefaultErrorHandler je final, preto implementujte ErrorHandlerInterface, všetky metódy delegujte na obalený DefaultErrorHandler ako v časti Vlastný error handler a v handleInputParams() vráťte new JsonApiResponse(400, ['status' => 'error', 'message' => 'wrong input', 'detail' => $errors]).

Ako pošlem 404 pre chýbajúci záznam? ​

Vráťte ho z handlera: new JsonApiResponse(404, [...]). Error handlery sú na neočakávané zlyhania. Pozrite si Handlery.

Kde uvidím výnimku? ​

V adresári logov Tracy, exception.log a HTML súbor pre každú výnimku. Príklad logovania to kontroluje.

Môžu chyby autorizácie mať vlastný stavový kód? ​

Rozhoduje váš error handler; handleAuthorization() dostane objekt autorizácie a môže z neho čítať čokoľvek. Pozrite si Autorizáciu.

Je pokazený výstup chybou v produkcii? ​

Len ak tam konfigurátor výstupy validuje. S EnvConfigurator a APP_ENV=production sa odpoveď pošle bez kontroly.

Vydané pod licenciou MIT.