Quelqu'un sait quel est le meilleur moyen de gérer les erreurs dans Laravel, y a-t-il des règles ou quelque chose à suivre?
Actuellement, je fais ceci:
public function store(Request $request)
{
$plate = Plate::create($request->all());
if ($plate) {
return $this->response($this->plateTransformer->transform($plate));
} else {
// Error handling ?
// Error 400 bad request
$this->setStatusCode(400);
return $this->responseWithError("Store failed.");
}
}
Et les paramètres setStatusCode et responseWithError proviennent du père de mon contrôleur:
public function setStatusCode($statusCode)
{
$this->statusCode = $statusCode;
return $this;
}
public function responseWithError ($message )
{
return $this->response([
'error' => [
'message' => $message,
'status_code' => $this->getStatusCode()
]
]);
}
Mais est-ce un bon moyen de gérer les erreurs d'API? Je vois un moyen différent de gérer les erreurs sur le Web. Quel est le meilleur?
Merci.
Essayez ceci, je l'ai utilisé dans mon projet (app/Exceptions/Handler.php)
public function render($request, Exception $exception)
{
if ($request->wantsJson()) { //add Accept: application/json in request
return $this->handleApiException($request, $exception);
} else {
$retval = parent::render($request, $exception);
}
return $retval;
}
Maintenant, gérer l'exception Api
private function handleApiException($request, Exception $exception)
{
$exception = $this->prepareException($exception);
if ($exception instanceof \Illuminate\Http\Exception\HttpResponseException) {
$exception = $exception->getResponse();
}
if ($exception instanceof \Illuminate\Auth\AuthenticationException) {
$exception = $this->unauthenticated($request, $exception);
}
if ($exception instanceof \Illuminate\Validation\ValidationException) {
$exception = $this->convertValidationExceptionToResponse($exception, $request);
}
return $this->customApiResponse($exception);
}
Après cette réponse de gestionnaire Api personnalisée
private function customApiResponse($exception)
{
if (method_exists($exception, 'getStatusCode')) {
$statusCode = $exception->getStatusCode();
} else {
$statusCode = 500;
}
$response = [];
switch ($statusCode) {
case 401:
$response['message'] = 'Unauthorized';
break;
case 403:
$response['message'] = 'Forbidden';
break;
case 404:
$response['message'] = 'Not Found';
break;
case 405:
$response['message'] = 'Method Not Allowed';
break;
case 422:
$response['message'] = $exception->original['message'];
$response['errors'] = $exception->original['errors'];
break;
default:
$response['message'] = ($statusCode == 500) ? 'Whoops, looks like something went wrong' : $exception->getMessage();
break;
}
if (config('app.debug')) {
$response['trace'] = $exception->getTrace();
$response['code'] = $exception->getCode();
}
$response['status'] = $statusCode;
return response()->json($response, $statusCode);
}
Toujours ajouter Accept: application/json
dans votre demande api ou json.
Laravel est déjà capable de gérer les réponses JSON par défaut.
Sans que vous personnalisiez la méthode de rendu dans app\Handler.php, vous pouvez simplement lancer une exception Symfony\Component\HttpKernel\Exception\HttpException, le gestionnaire par défaut reconnaîtra si l'en-tête de demande contient Accept: application/json et imprimera un json message d'erreur en conséquence.
Si le mode débogage est activé, la sortie de pile sera également générée au format json.
Voici un exemple rapide:
<?php
...
use Symfony\Component\HttpKernel\Exception\HttpException;
class ApiController
{
public function myAction(Request $request)
{
try {
// My code...
} catch (\Exception $e) {
throw new HttpException(500, $e->getMessage());
}
return $myObject;
}
}
Voici la réponse de laravel avec debug off
{
"message": "My custom error"
}
Et voici la réponse avec debug sur
{
"message": "My custom error",
"exception": "Symfony\\Component\\HttpKernel\\Exception\\HttpException",
"file": "D:\\www\\myproject\\app\\Http\\Controllers\\ApiController.php",
"line": 24,
"trace": [
{
"file": "D:\\www\\myproject\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\ControllerDispatcher.php",
"line": 48,
"function": "myAction",
"class": "App\\Http\\Controllers\\ApiController",
"type": "->"
},
{
"file": "D:\\www\\myproject\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Route.php",
"line": 212,
"function": "dispatch",
"class": "Illuminate\\Routing\\ControllerDispatcher",
"type": "->"
},
...
]
}
En utilisant HttpException, l'appel renvoie le code d'état http de votre choix (dans ce cas, l'erreur de serveur interne 500)
À mon avis, je vais garder les choses simples.
Renvoyer une réponse avec le code d'erreur HTTP et un message personnalisé.
return response()->json(['error' => 'You need to add a card first'], 500);
Ou si vous voulez lancer une erreur surprise, vous pouvez faire:
try {
// some code
} catch (Exception $e) {
return response()->json(['error' => $e->getMessage()], 500);
}
Vous pouvez même l'utiliser pour envoyer des réponses réussies:
return response()->json(['activeSubscription' => $this->getActiveSubscription()], 200);
Ainsi, quel que soit le service consommant votre API, il peut s’attendre à recevoir les mêmes réponses pour les mêmes demandes.
Vous pouvez également voir à quel point vous pouvez le rendre flexible en transmettant le code d'état HTTP.