php - float - Laravel 5: maneja excepciones cuando la solicitud quiere JSON
laravel validation float (6)
Basándome en la función de renderización del controlador de @Jonathon, simplemente modificaría las condiciones para excluir las instancias de ValidationException.
// If the request wants JSON + exception is not ValidationException
if ($request->wantsJson() && ( ! $exception instanceof ValidationException))
Laravel 5 devuelve errores de validación en JSON, si corresponde.
El método completo en App / Exceptions / Handler.php:
/**
* Render an exception into an HTTP response.
*
* @param /Illuminate/Http/Request $request
* @param /Exception $exception
* @return /Illuminate/Http/Response
*/
public function render($request, Exception $exception)
{
// If the request wants JSON + exception is not ValidationException
if ($request->wantsJson() && ( ! $exception instanceof ValidationException))
{
// Define the response
$response = [
''errors'' => ''Sorry, something went wrong.''
];
// If the app is in debug mode
if (config(''app.debug''))
{
// Add the exception class name, message and stack trace to response
$response[''exception''] = get_class($exception); // Reflection might be better here
$response[''message''] = $exception->getMessage();
$response[''trace''] = $exception->getTrace();
}
// Default response of 400
$status = 400;
// If this exception is an instance of HttpException
if ($this->isHttpException($exception))
{
// Grab the HTTP status code from the Exception
$status = $exception->getCode();
}
// Return a JSON response with the response array and status code
return response()->json($response, $status);
}
return parent::render($request, $exception);
}
Estoy cargando archivos a través de AJAX en Laravel 5. Tengo casi todo funcionando, excepto una cosa.
Cuando trato de subir un archivo que es demasiado grande (más grande que upload_max_filesize
y post_max_size
me sale una TokenMismatchException lanzada.
Esto es de esperar, sin embargo, porque sé que mi entrada estará vacía si se exceden estos límites. La entrada vacía significa que no se recibió _token
por lo que el middleware responsable de verificar los tokens de CSRF está causando problemas.
Sin embargo, mi problema no es que esta excepción haya sido lanzada, sino cómo se está procesando. Cuando Laravel atrapa esta excepción, está escupiendo el HTML de la página genérica de Whoops (con una carga de rastreo de pila desde que estoy en modo de depuración).
¿Cuál es la mejor manera de manejar esta excepción para que JSON se devuelva a través de AJAX (o cuando se solicite JSON) mientras se mantiene el comportamiento predeterminado de lo contrario?
Editar: Esto parece suceder independientemente de la excepción lanzada. Acabo de intentar hacer una solicitud a través de AJAX (Datatype: JSON) a una ''página'' que no existe en un intento de obtener un 404 y sucede lo mismo: se devuelve HTML, nada compatible con JSON.
En su aplicación, debe tener la app/Http/Middleware/VerifyCsrfToken.php
. En ese archivo puede manejar cómo se ejecuta el middleware. Para que pueda verificar si la solicitud es ajax y manejar eso como lo desee.
Alternativamente, y probablemente una mejor solución, sería editar el manejador de excepciones para devolver json. Ver app/exceptions/Handler.php
, algo así como el siguiente sería un punto de partida
public function render($request, Exception $e)
{
if ($request->ajax() || $request->wantsJson())
{
$json = [
''success'' => false,
''error'' => [
''code'' => $e->getCode(),
''message'' => $e->getMessage(),
],
];
return response()->json($json, 400);
}
return parent::render($request, $e);
}
He alterado varias implementaciones que se encuentran aquí para trabajar en Laravel 5.3. La principal diferencia es que el mío devolverá los textos de estado HTTP correctos
En su función render () en la aplicación / Exceptions / Handler.php, agregue este fragmento a la parte superior:
if ($request->wantsJson()) {
return $this->renderExceptionAsJson($request, $exception);
}
Contenido de renderExceptionAsJson:
/**
* Render an exception into a JSON response
*
* @param $request
* @param Exception $exception
* @return SymfonyResponse
*/
protected function renderExceptionAsJson($request, Exception $exception)
{
// Currently converts AuthorizationException to 403 HttpException
// and ModelNotFoundException to 404 NotFoundHttpException
$exception = $this->prepareException($exception);
// Default response
$response = [
''error'' => ''Sorry, something went wrong.''
];
// Add debug info if app is in debug mode
if (config(''app.debug'')) {
// Add the exception class name, message and stack trace to response
$response[''exception''] = get_class($exception); // Reflection might be better here
$response[''message''] = $exception->getMessage();
$response[''trace''] = $exception->getTrace();
}
$status = 400;
// Build correct status codes and status texts
switch ($exception) {
case $exception instanceof ValidationException:
return $this->convertValidationExceptionToResponse($exception, $request);
case $exception instanceof AuthenticationException:
$status = 401;
$response[''error''] = Response::$statusTexts[$status];
break;
case $this->isHttpException($exception):
$status = $exception->getStatusCode();
$response[''error''] = Response::$statusTexts[$status];
break;
default:
break;
}
return response()->json($response, $status);
}
Nota rápida sobre esto ... En Laravel 5.5, la excepción se llama "$ exception" y no "$ e" en el método.
Usando el código de @ Jonathon, aquí hay una solución rápida para Laravel / Lumen 5.3 :)
/**
* Render an exception into an HTTP response.
*
* @param /Illuminate/Http/Request $request
* @param /Exception $e
* @return /Illuminate/Http/Response
*/
public function render($request, Exception $e)
{
// If the request wants JSON (AJAX doesn''t always want JSON)
if ($request->wantsJson())
{
// Define the response
$response = [
''errors'' => ''Sorry, something went wrong.''
];
// If the app is in debug mode
if (config(''app.debug''))
{
// Add the exception class name, message and stack trace to response
$response[''exception''] = get_class($e); // Reflection might be better here
$response[''message''] = $e->getMessage();
$response[''trace''] = $e->getTrace();
}
// Default response of 400
$status = 400;
// If this exception is an instance of HttpException
if ($e instanceof HttpException)
{
// Grab the HTTP status code from the Exception
$status = $e->getStatusCode();
}
// Return a JSON response with the response array and status code
return response()->json($response, $status);
}
// Default to the parent class'' implementation of handler
return parent::render($request, $e);
}
Voy a tomar una foto de este teniendo en cuenta la respuesta de @Tader y los comentarios de @Tyler Crompton:
aplicación / Excepciones / Handler.php
/**
* Render an exception into an HTTP response.
*
* @param /Illuminate/Http/Request $request
* @param /Exception $e
* @return /Illuminate/Http/Response
*/
public function render($request, Exception $e)
{
// If the request wants JSON (AJAX doesn''t always want JSON)
if ($request->wantsJson()) {
// Define the response
$response = [
''errors'' => ''Sorry, something went wrong.''
];
// If the app is in debug mode
if (config(''app.debug'')) {
// Add the exception class name, message and stack trace to response
$response[''exception''] = get_class($e); // Reflection might be better here
$response[''message''] = $e->getMessage();
$response[''trace''] = $e->getTrace();
}
// Default response of 400
$status = 400;
// If this exception is an instance of HttpException
if ($this->isHttpException($e)) {
// Grab the HTTP status code from the Exception
$status = $e->getStatusCode();
}
// Return a JSON response with the response array and status code
return response()->json($response, $status);
}
// Default to the parent class'' implementation of handler
return parent::render($request, $e);
}