2016-02-11 2 views
10

Ich baue eine REST-API mit Laravel 5.Wie gibt man AJAX-Fehler von einem Laravel-Controller zurück?

In Laravel 5 können Sie App\Http\Requests\Request Unterklasse die Validierungsregeln zu definieren, die erfüllt sein müssen, bevor eine bestimmte Route bearbeitet werden. Zum Beispiel:

<?php 

namespace App\Http\Requests; 

use App\Http\Requests\Request; 

class BookStoreRequest extends Request { 

    public function authorize() { 
     return true; 
    } 

    public function rules() { 
     return [ 
      'title' => 'required', 
      'author_id' => 'required' 
     ]; 
    } 
} 

Wenn ein Client über eine AJAX-Anforderung die entsprechende Route lädt, und BookStoreRequest stellt fest, dass der Antrag die Regeln nicht erfüllt, wird es automatisch die Fehler zurück (s) als JSON-Objekt. Zum Beispiel:

{ 
    "title": [ 
    "The title field is required." 
    ] 
} 

Jedoch kann die Request::rules() Methode nur bestätigen Eingabe-und auch wenn die Eingabe gültig ist, können andere Arten von Fehlern auftreten könnten, nachdem die Anforderung wurde bereits akzeptiert und übergab an die Steuerung aus. Zum Beispiel, sagen wir mal, dass der Controller das neue Buch Informationen in eine Datei aus irgendeinem Grund, aber die Datei kann nicht geöffnet werden, schreiben muss:

<?php 

namespace App\Http\Controllers; 

use Illuminate\Http\Request; 

use App\Http\Requests; 
use App\Http\Controllers\Controller; 

use App\Http\Requests\BookCreateRequest; 

class BookController extends Controller { 

    public function store(BookStoreRequest $request) { 

     $file = fopen('/path/to/some/file.txt', 'a'); 

     // test to make sure we got a good file handle 
     if (false === $file) { 
      // HOW CAN I RETURN AN ERROR FROM HERE? 
     } 

     fwrite($file, 'book info goes here'); 
     fclose($file); 

     // inform the browser of success 
     return response()->json(true); 

    } 

} 

Offensichtlich konnte ich nur die(), aber das ist super hässlich. Ich würde meine Fehlermeldung lieber im selben Format wie die Validierungsfehler zurückgeben. Wie folgt aus:

{ 
    "myErrorKey": [ 
    "A filesystem error occurred on the server. Please contact your administrator." 
    ] 
} 

konnte ich mein eigenes JSON-Objekt erstellen und zurückgeben, aber sicherlich Laravel nativ unterstützt dies.

Was ist der beste/sauberste Weg, dies zu tun? Oder gibt es eine bessere Möglichkeit, Laufzeitfehler (im Gegensatz zu Validierungszeit) von einer Laravel-REST-API zurückzugeben?

+0

Warum können Sie nicht einfach ein 'return response() -> json ([ 'error' => 'Ihre eigene Nachricht']);'? –

+0

Sie können eine benutzerdefinierte JSON-Antwortklasse erstellen – Digitlimit

+0

'return response() -> json()' würde es mit 200 OK zurückgeben. Ich möchte einen geeigneten Antwortcode verwenden, der nicht 200 ist (z. B. 500 Interner Serverfehler). Ja, ich könnte das auch per Hand schreiben - ich habe einfach angenommen, dass Laravel bereits eine eingebaute, strukturiertere Methode zur Verfügung gestellt hat. Vielleicht ist das eine falsche Annahme. – greenie2600

Antwort

13

Sie können den Statuscode in Ihrer Json Antwort wie unten:

return Response::json(['error' => 'Error msg'], 404); // Status code here 

Oder einfach nur durch die Hilfsfunktion mit:

return response()->json(['error' => 'Error msg'], 404); // Status code here 
+0

Verwenden Sie die Funktion response(), nicht $ response() –

3

Sie es in vielerlei Hinsicht tun können.

Zuerst Sie die einfachen response()->json() durch die Bereitstellung einen Statuscode verwenden:

return response()->json(/** response **/, 401); 

Oder in einem complexe Weg, um sicherzustellen, dass jeder Fehler eine Json Antwort ist, können Sie einen Exception-Handler eingerichtet Fange eine spezielle Ausnahme und gib json zurück.

öffnen App\Exceptions\Handler und wie folgt vorgehen:

class Handler extends ExceptionHandler 
{ 
    /** 
    * A list of the exception types that should not be reported. 
    * 
    * @var array 
    */ 
    protected $dontReport = [ 
     HttpException::class, 
     HttpResponseException::class, 
     ModelNotFoundException::class, 
     NotFoundHttpException::class, 
     // Don't report MyCustomException, it's only for returning son errors. 
     MyCustomException::class 
    ]; 

    public function render($request, Exception $e) 
    { 
     // This is a generic response. You can the check the logs for the exceptions 
     $code = 500; 
     $data = [ 
      "error" => "We couldn't hadle this request. Please contact support." 
     ]; 

     if($e instanceof MyCustomException) { 
      $code = $e->getStatusCode(); 
      $data = $e->getData(); 
     } 

     return response()->json($data, $code); 
    } 
} 

Dieses eine json für jede Ausnahme in der Anwendung geworfen zurück. Jetzt schaffen wir MyCustomException, zum Beispiel in app/Ausnahmen:

class MyCustomException extends Exception { 

    protected $data; 
    protected $code; 

    public static function error($data, $code = 500) 
    { 
     $e = new self; 
     $e->setData($data); 
     $e->setStatusCode($code); 

     throw $e; 
    } 

    public function setStatusCode($code) 
    { 
     $this->code = $code; 
    } 

    public function setData($data) 
    { 
     $this->data = $data; 
    } 


    public function getStatusCode() 
    { 
     return $this->code; 
    } 

    public function getData() 
    { 
     return $this->data; 
    } 
} 

können wir gerade jetzt MyCustomException oder jede Ausnahme MyCustomException Verlängerung verwenden, um einen json Fehler zurückzukehren. Jetzt

public function store(BookStoreRequest $request) { 

    $file = fopen('/path/to/some/file.txt', 'a'); 

    // test to make sure we got a good file handle 
    if (false === $file) { 
     MyCustomException::error(['error' => 'could not open the file, check permissions.'], 403); 

    } 

    fwrite($file, 'book info goes here'); 
    fclose($file); 

    // inform the browser of success 
    return response()->json(true); 

} 

, nicht nur über MyCustomException geworfen Ausnahmen einen json Fehler zurück, aber jede andere Ausnahme im Allgemeinen geworfen.