Saltar al contenido

Laravel API, cómo manejar correctamente los errores

Posterior a consultar especialistas en el tema, programadores de deferentes áreas y maestros dimos con la respuesta al dilema y la dejamos plasmada en este post.

Solución:

Prueba esto, lo he usado en mi proyecto. (aplicación/Excepciones/Manejador.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;

Ahora maneja la excepción Api

private function handleApiException($request, Exception $exception)

    $exception = $this->prepareException($exception);

    if ($exception instanceof IlluminateHttpExceptionHttpResponseException) 
        $exception = $exception->getResponse();
    

    if ($exception instanceof IlluminateAuthAuthenticationException) 
        $exception = $this->unauthenticated($request, $exception);
    

    if ($exception instanceof IlluminateValidationValidationException) 
        $exception = $this->convertValidationExceptionToResponse($exception, $request);
    

    return $this->customApiResponse($exception);

Después de esa respuesta del controlador Api personalizado

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);

Añadir siempre Accept: application/json en su solicitud api o json.

Laravel ya puede administrar las respuestas json de forma predeterminada.

Sin personalizar el método de renderizado en appHandler.php, puedes simplemente lanzar un SymfonyComponentHttpKernelExceptionHttpException, el controlador predeterminado reconocerá si el encabezado de la solicitud contiene Aceptar: aplicación/json e imprimirá un mensaje de error json en consecuencia.

Si el modo de depuración está habilitado, también generará el stacktrace en formato json.

Aquí hay un ejemplo rápido:

getMessage());
        

        return $myObject;
    

Aquí está la respuesta de laravel con depuración desactivada


    "message": "My custom error"

Y aquí está la respuesta con depuración en


    "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": "->"
        ,

        ...
    ]

Al usar HttpException, la llamada devolverá el código de estado http de su elección (en este caso, interno). Error del Servidor 500)

En mi opinión, lo mantendría simple.

Devuelve una respuesta con el código de error HTTP y un mensaje personalizado.

return response()->json(['error' => 'You need to add a card first'], 500);

O si desea arrojar un error detectado, puede hacerlo:

   try 
     // some code
     catch (Exception $e) 
        return response()->json(['error' => $e->getMessage()], 500);
    

Incluso puede usar esto para enviar respuestas exitosas:

return response()->json(['activeSubscription' => $this->getActiveSubscription()], 200);

De esta manera, sin importar qué servicio consuma su API, puede esperar recibir las mismas respuestas para las mismas solicitudes.

También puede ver qué tan flexible puede hacerlo al pasar el código de estado HTTP.

Comentarios y valoraciones del tutorial

Al final de todo puedes encontrar las críticas de otros programadores, tú incluso puedes dejar el tuyo si dominas el tema.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *