laravel 错误处理,接口错误返回json

Laravel 默认已经为我们配置好了错误和异常处理,我们在 App\Exceptions\Handler 类中触发异常并将响应返回给用户。
report方法只是将异常传递给异常被记录的基类,我们这里主要是针对 render 的修改:


public function render($request, Exception $exception)
        $response = [];
        $error = $this->convertExceptionToResponse($exception);
        $response['status'] = $error->getStatusCode();
        $response['msg'] = 'something error';
        if(config('app.debug')) {
            $response['msg'] = empty($exception->getMessage()) ? 'something error' : $exception->getMessage();
            if($error->getStatusCode() >= 500) {
                if(config('app.debug')) {
                    $response['trace'] = $exception->getTraceAsString();
                    $response['code'] = $exception->getCode();
        $response['data'] = [];
        return response()->json($response, $error->getStatusCode());
        return parent::render($request, $exception);

$request->is(‘api/*’) 用于判断是否是 接口请求

$response 数组你可以依据你的接口返回格式统一一下。



<div class="post-text" itemprop="text"> <p>I have to receive a POST request from a client to my REST app in laravel 5. I'm follow the documentation related to validation, it said that when is an AJAX request laravel do not generate a redirect response, instead it will generate a JSON response with errors(<a href="" rel="nofollow noreferrer"></a>). But when I make the call from a REST client I'm getting this response:</p> <pre><code><!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <meta http-equiv="refresh" content="0;url=" /> <title>Redirecting to</title> </head> <body> Redirecting to <a href=""></a>. </body> </html> </code></pre> <p>AdultoPost class *********************</p> <pre><code>class AdultoPost extends FormRequest { public function authorize() { return true; } public function rules() { return [ 'Profesion' => "max:50", "EstadoCivil" => "required", "FamiliaReconstituida" => "required", "SolteroConHijo" => "required", "Viudo" => "required", "NoHijos" => "required" ]; } } </code></pre> <p>AdultoController **************</p> <pre><code> public function post(AdultoPost $request, Adulto $adulto, Paciente $paciente, Persona $persona) { $persona = Persona::create($request->all()); $adulto = Adulto::create($request->all()); $paciente = Paciente::create($request->all()); return $adulto; } </code></pre> <p>If I change AdultoPost class for Request and put the validation rules inside the post function and catch a ValidationException I get this error response "The given data was invalid". Which is not what I want. I would like to send to the client which fields were invalid and why. </p> <p>I'm making the request from REST API plugin of VSCODE, and from REST API TESTING extension from chrome, and now I'm installing POSTMAN to continue testing</p> <pre><code>POST Content-Type: application/json Accept: application/json { "FechaInicio":"2017-09-10", "MotivoConsulta":"un motivo real", "ComoConocio":"como conocio" } </code></pre> </div>

路由返回了无效的JSON。 也许是一个例外被抛出?

<div class="post-text" itemprop="text"> <p>I've been working on adding <a href="" rel="nofollow noreferrer">JWT authentication</a> to my Lumen API. Please bare in mind I am new to Lumen, API design and TDD. Before adding the authentication all of tests were passing. Honestly, everything seems to be working just fine except when I run phpunit. What's difficult to understand is when I run the same test in postman I have no issues, however when I dump the response in phpunit i get <code>NULL</code>. Perhaps a fresh set of eyes can help me out?</p> <p>I've added the jwt.auth middleware to my restricted routes:</p> <p><strong>routes.php</strong></p> <pre><code>// all other code omitted $app->group([ 'prefix' => $version . '/authors', 'middleware' => 'jwt.auth', 'namespace' => 'App\Http\Controllers', ], function ($app) { $app->get('/{id:[\d]+}', ['as' => '', 'uses' => 'AuthorsController@show']); }); </code></pre> <p>Part of my controller is as follows:</p> <p><strong>AuthorsController.php</strong></p> <pre><code>class AuthorsController extends Controller { // all other code omitted public function show($id) { return $this->item(Author::findOrFail($id), new AuthorTransformer()); } } </code></pre> <p>My model is as follows</p> <p><strong>Author.php</strong></p> <pre><code>class Author extends Model { /** * The attributes that are mass assignable * * @var array */ protected $fillable = ['name', 'biography', 'gender']; public function books() { return $this->hasMany(Book::class); } } </code></pre> <p>And my Transformer is as follows:</p> <p><strong>AuthorTransformer.php</strong></p> <pre><code>class AuthorTransformer extends TransformerAbstract { protected $availableIncludes = [ 'books', ]; public function includeBooks(Author $author) { return $this->collection($author->books, new BookTransformer()); } /** * Transform an author model * * @param Author $author * @return array */ public function transform(Author $author) { return [ 'id' => $author->id, 'name' => $author->name, 'gender' => $author->gender, 'biography' => $author->biography, 'created' => $author->created_at->toIso8601String(), 'updated' => $author->created_at->toIso8601String(), ]; } } </code></pre> <p>And my tests are as follows:</p> <p><strong>TestCase.php</strong></p> <pre><code>class TestCase extends Laravel\Lumen\Testing\TestCase { // all other code omitted /** * Convenience method for creating a user * * @return $user */ protected function userFactory() { $user = factory(\App\User::class, 1)->create(['password' => app('hash')->make('supersecret')]); return $user; } /** * Convenience method for getting jwt and authenticating * * @return $body */ protected function jwtAuthTest($method, $url, $body = []) { $user = $this->userFactory(); $token = JWTAuth::fromUser($user); JWTAuth::setToken($token); $headers = array( "Accept" => "application/json", "Authorization" => "Bearer " . $token, ); switch ($method) { case 'get': $this->get($url, $body, $headers); break; case 'post': $this->post($url, $body, $headers); break; case 'put': $this->put($url, $body, $headers); break; case 'patch': $this->patch($url, $body, $headers); break; case 'delete': $this->delete($url, $body, $headers); break; } $data = json_decode($this->response->getContent(), true); return $data; } } </code></pre> <p><strong>AuthorsControllerTest.php</strong></p> <pre><code>class AuthorsControllerTest extends TestCase { // all other code omitted /** @test **/ public function show_should_fail_on_an_invalid_author() { $body = $this->jwtAuthTest('get', '/v1/authors/1234'); // this works fine... $this->seeStatusCode(Response::HTTP_NOT_FOUND); // NULL?? var_dump($body); } } </code></pre> <p>My response should be:</p> <pre><code>{ "error": { "message": "Not Found", "status": 404 } } </code></pre> <p>However I am getting <code>NULL</code></p> <p>When I test the same route with a valid token in Postman I get, which is what I'm expected in my tests:</p> <pre><code>{ "error": { "message": "Not Found", "status": 404 } } </code></pre> <p>Suddenly my route is returning null in phpunit tests. I can't seem to figure out why?</p> <p>My handler is as follows:</p> <pre><code>// all other code omitted class Handler extends ExceptionHandler { /** * A list of the exception types that should not be reported. * * @var array */ protected $dontReport = [ AuthorizationException::class, HttpException::class, ModelNotFoundException::class, ValidationException::class, ]; /** * Report or log an exception. * * This is a great spot to send exceptions to Sentry, Bugsnag, etc. * * @param \Exception $e * @return void */ public function report(Exception $e) { parent::report($e); } /** * 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()) { $response = [ 'message' => (string) $e->getMessage(), 'status' => 400, ]; if ($e instanceof HttpException) { $response['message'] = Response::$statusTexts[$e->getStatusCode()]; $response['status'] = $e->getStatusCode(); } else if ($e instanceof ModelNotFoundException) { $response['message'] = Response::$statusTexts[Response::HTTP_NOT_FOUND]; $response['status'] = Response::HTTP_NOT_FOUND; } if ($this->isDebugMode()) { $response['debug'] = [ 'exception' => get_class($e), 'trace' => $e->getTrace(), ]; } return response()->json(['error' => $response], $response['status']); } return parent::render($request, $e); } } </code></pre> <p>When my test fails I get:</p> <pre><code>There was 1 failure: 1) Tests\App\Http\Controllers\AuthorsControllerTest::show_should_fail_on_an_invalid_author Invalid JSON was returned from the route. Perhaps an exception was thrown? </code></pre> <p>Please let me know if you need anything else and thank you in advance.</p> <p>Source code: <a href="" rel="nofollow noreferrer"></a></p> </div>
©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
钱包余额 0