Gestion des exceptions
Configuration
config/exception.php
return [
// Ici, vous configurez la classe de gestion des exceptions
'' => support\exception\Handler::class,
];
En mode multi-application, vous pouvez configurer une classe de gestion des exceptions distincte pour chaque application, voir multi-application.
Classe de gestion des exceptions par défaut
Les exceptions dans webman sont par défaut gérées par la classe support\exception\Handler
. Vous pouvez modifier le fichier de configuration config/exception.php
pour changer la classe de gestion des exceptions par défaut. La classe de gestion des exceptions doit implémenter l'interface Webman\Exception\ExceptionHandlerInterface
.
interface ExceptionHandlerInterface
{
/**
* Enregistrer le journal
* @param Throwable $e
* @return mixed
*/
public function report(Throwable $e);
/**
* Rendre la réponse
* @param Request $request
* @param Throwable $e
* @return Response
*/
public function render(Request $request, Throwable $e) : Response;
}
Rendre la réponse
La méthode render
dans la classe de gestion des exceptions est utilisée pour rendre la réponse.
Si la valeur debug
dans le fichier de configuration config/app.php
est true
(ci-après appelée app.debug=true
), des informations détaillées sur l'exception seront renvoyées, sinon des informations d'exception abrégées seront renvoyées.
Si la requête attend une réponse au format json, les informations d'exception renvoyées seront au format json, similaire à
{
"code": "500",
"msg": "Informations sur l'exception"
}
Si app.debug=true
, les données json auront un champ trace
supplémentaire renvoyant la pile d'appels détaillée.
Vous pouvez écrire votre propre classe de gestion des exceptions pour modifier la logique de gestion des exceptions par défaut.
Exception d'affaires BusinessException
Parfois, nous voulons interrompre une requête dans une fonction imbriquée et renvoyer un message d'erreur au client, nous pouvons le faire en lançant une BusinessException
.
Par exemple :
<?php
namespace app\controller;
use support\Request;
use support\exception\BusinessException;
class FooController
{
public function index(Request $request)
{
$this->checkInput($request->post());
return response('hello index');
}
protected function checkInput($input)
{
if (!isset($input['token'])) {
throw new BusinessException('Erreur de paramètre', 3000);
}
}
}
L'exemple ci-dessus renverra un
{"code": 3000, "msg": "Erreur de paramètre"}
Attention
L'exception d'affaires BusinessException n'a pas besoin d'être capturée par un try, le framework la capture automatiquement et renvoie une sortie appropriée en fonction du type de requête.
Exception d'affaires personnalisée
Si la réponse ci-dessus ne correspond pas à vos besoins, par exemple, si vous souhaitez que msg
soit remplacé par message
, vous pouvez créer une MyBusinessException
.
Créez app/exception/MyBusinessException.php
avec le contenu suivant
<?php
namespace app\exception;
use support\exception\BusinessException;
use Webman\Http\Request;
use Webman\Http\Response;
class MyBusinessException extends BusinessException
{
public function render(Request $request): ?Response
{
// Pour les requêtes json, retourner des données json
if ($request->expectsJson()) {
return json(['code' => $this->getCode() ?: 500, 'message' => $this->getMessage()]);
}
// Pour les requêtes non json, retourner une page
return new Response(200, [], $this->getMessage());
}
}
Ainsi, lorsque l'appel d'affaires se produit
use app\exception\MyBusinessException;
throw new MyBusinessException('Erreur de paramètre', 3000);
la requête json recevra une réponse json similaire à celle-ci
{"code": 3000, "message": "Erreur de paramètre"}
Conseil
Comme l'exception BusinessException appartient aux exceptions d'affaires (par exemple, erreur de saisie utilisateur), elle est prévisible et le framework ne la considère donc pas comme une erreur fatale et ne l'enregistre pas dans le journal.
Résumé
Chaque fois que vous souhaitez interrompre la requête actuelle et renvoyer des informations au client, envisagez d'utiliser l'exception BusinessException
.