Gestion des exceptions
Configuration
config/exception.php
return [
// Configurez ici la classe de gestion des exceptions
'' => support\exception\Handler::class,
];
En mode d'application multiple, vous pouvez configurer une classe de gestion des exceptions distincte pour chaque application, voir Application multiple
Classe de gestion des exceptions par défaut
Les exceptions dans webman sont gérées par défaut par la classe support\exception\Handler
. Vous pouvez modifier la classe de gestion des exceptions par défaut en modifiant le fichier de configuration config/exception.php
. La classe de gestion des exceptions doit implémenter l'interface Webman\Exception\ExceptionHandlerInterface
.
interface ExceptionHandlerInterface
{
/**
* Enregistrer les logs
* @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 une réponse
La méthode render
dans la classe de gestion des exceptions est utilisée pour rendre une réponse.
Si la valeur de debug
dans le fichier de configuration config/app.php
est true
(abrégé en app.debug=true
), des informations détaillées sur l'exception seront renvoyées, sinon des informations succinctes sur l'exception seront renvoyées.
Si la demande attend une réponse en JSON, les informations sur l'exception seront renvoyées au format JSON, par exemple
{
"code": "500",
"msg": "Informations sur l'exception"
}
Si app.debug=true
, les données JSON incluront également un champ trace
renvoyant une 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 métier BusinessException
Parfois, nous voulons interrompre une requête à l'intérieur d'une fonction imbriquée et renvoyer un message d'erreur au client. Dans ce cas, 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"}
Remarque
Une BusinessException n'a pas besoin d'être capturée par un bloc try-catch, le framework la capture automatiquement et renvoie une sortie appropriée en fonction du type de requête.
Exception métier personnalisée
Si la réponse ci-dessus ne correspond pas à vos besoins, par exemple si vous souhaitez changer msg
en message
, vous pouvez créer une MyBusinessException
personnalisée.
Créez un nouveau fichier 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
{
// Renvoi des données JSON pour les requêtes JSON
if ($request->expectsJson()) {
return json(['code' => $this->getCode() ?: 500, 'message' => $this->getMessage()]);
}
// Renvoi d'une page pour les requêtes non-JSON
return new Response(200, [], $this->getMessage());
}
}
De cette manière, lorsque vous appelez
use app\exception\MyBusinessException;
throw new MyBusinessException('Erreur de paramètre', 3000);
une requête JSON recevra une réponse au format JSON similaire à la suivante
{"code": 3000, "message": "Erreur de paramètre"}
Remarque
Comme l'exception BusinessException est une exception métier (par exemple, une erreur de saisie utilisateur) et est prévisible, le framework ne la considère pas comme une erreur fatale et ne la journalise pas.
Conclusion
Lorsque vous souhaitez interrompre une requête en cours et renvoyer des informations au client, vous pouvez envisager d'utiliser l'exception BusinessException
.