Ich entwickle eine Art RESTful-API. Wenn ein Fehler auftritt, erhalte ich einen App::abort($code, $message)
-Fehler.
Das Problem ist: Ich möchte, dass er ein Json-Array mit den Schlüsseln "Code" und "Message" wirft, von denen jeder die oben genannten Daten enthält.
Array
(
[code] => 401
[message] => "Invalid User"
)
Weiß jemand, ob es möglich ist und wenn ja, wie mache ich das?
gehe zu deinem app/start/global.php
.
Dadurch werden alle Fehler für 401
und 404
in einen benutzerdefinierten Json-Fehler anstelle des Whoops-Stacktrace konvertiert. Füge das hinzu:
App::error(function(Exception $exception, $code)
{
Log::error($exception);
$message = $exception->getMessage();
// switch statements provided in case you need to add
// additional logic for specific error code.
switch ($code) {
case 401:
return Response::json(array(
'code' => 401,
'message' => $message
), 401);
case 404:
$message = (!$message ? $message = 'the requested resource was not found' : $message);
return Response::json(array(
'code' => 404,
'message' => $message
), 404);
}
});
Dies ist eine von vielen Optionen, um diese Fehler zu behandeln.
Für die Erstellung einer API ist es am besten, einen eigenen Helfer wie Responser::error(400, 'damn')
zu erstellen, der die Response
-Klasse erweitert.
Etwas wie:
public static function error($code = 400, $message = null)
{
// check if $message is object and transforms it into an array
if (is_object($message)) { $message = $message->toArray(); }
switch ($code) {
default:
$code_message = 'error_occured';
break;
}
$data = array(
'code' => $code,
'message' => $code_message,
'data' => $message
);
// return an error
return Response::json($data, $code);
}
Sie können ein Array an die zurückgegebene JSON-Antwort übergeben:
$returnData = array(
'status' => 'error',
'message' => 'An error occurred!'
);
return Response::json($returnData, 500);
Ich verwende (Laravel 5.2):
Gemäß: https://laravel.com/docs/5.2/errors können wir eine benutzerdefinierte Renderfunktion für Fehler in app\Exceptions\Handler.php
angeben. Alles was ich getan habe, war meine Renderfunktion dahingehend zu ändern:
/**
* Render an exception into an HTTP response.
* Updated to return json for a request that wantsJson
* i.e: specifies
* Accept: application/json
* in its header
*
* @param \Illuminate\Http\Request $request
* @param \Exception $e
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $e)
{
if ($request->ajax() || $request->wantsJson()) {
return response()->json(
$this->getJsonMessage($e),
$this->getExceptionHTTPStatusCode($e)
);
}
return parent::render($request, $e);
}
protected function getJsonMessage($e){
// You may add in the code, but it's duplication
return [
'status' => 'false',
'message' => $e->getMessage()
];
}
protected function getExceptionHTTPStatusCode($e){
// Not all Exceptions have a http status code
// We will give Error 500 if none found
return method_exists($e, 'getStatusCode') ?
$e->getStatusCode() : 500;
}
Danach müssen Sie nur noch sicherstellen, dass alle Ihre API-Anforderungen den Header Accept: application/json
angeben. Hoffe das hilft :)
Hier ist, was ich in 5.6 verwendet habe, um den gleichen Antworttyp wie die eingebaute validate
-Methode zurückzugeben:
response()->json(['errors' => ['email' => ['The email is invalid.']]], 422);
Laut Ibrahims Antwort will nicht jede Ajax-Anfrage JSON. Das Beantworten des "Statuscodes" und des "Status" ist unnötig, da beide dasselbe bedeuten. Darüber hinaus muss in der Antwort überhaupt nicht "status" erwähnt werden, da der Antwortcode dies "sagt". So etwas sollte perfekt funktionieren:
/**
* 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 ($request->wantsJson())
return response()->json(
['message' => $e->getMessage()],
method_exists($e, 'getStatusCode') ? $e->getStatusCode() : 500);
return parent::render($request, $e);
}
In Laravel5.6 lege ich normalerweise eine benutzerdefinierte Renderfunktion für Fehler in app\Exceptions\Handler.php
fest. Alles was ich getan habe, war meine Renderfunktion dahingehend zu ändern:
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $e
*
* @return Response
*/
public function render($request, Exception $e)
{
if ($request->wantsJson() && !($e instanceof ValidationException)) {
$response = [
'message' => (string)$e->getMessage(),
'status_code' => 400,
];
if ($e instanceof HttpException) {
$response['message'] = Response::$statusTexts[$e->getStatusCode()];
$response['status_code'] = $e->getStatusCode();
} else if ($e instanceof ModelNotFoundException) {
$response['message'] = Response::$statusTexts[Response::HTTP_NOT_FOUND];
$response['status_code'] = Response::HTTP_NOT_FOUND;
}
if ($this->isDebugMode()) {
$response['debug'] = [
'exception' => get_class($e),
'trace' => $e->getTrace()
];
}
return response()->json([
'status' => 'failed',
'status_code' => $response['status_code'],
'massage' => $response['message'],
], $response['status_code']);
}
return parent::render($request, $e);
}