2017-07-31 75 views
0

我建设我的API和我successfuly设法赶上中间件我周围设置了我的路线就像下面一些误区:如何捕捉“过多尝试”例外中间件Laravel 5

Route::group(['middleware' => \App\Http\Middleware\ExceptionHandlerMiddleware::class], function() { 

    Route::resource('/address', 'AddressController'); 

    Route::resource('/country', 'CountryController'); 

    Route::resource('/phone', 'PhoneController'); 

    Route::resource('/user', 'UserController'); 
}); 

的中间件设法抓住以下情况除外:

  • Illuminate\Database\Eloquent\ModelNotFoundException
  • Illuminate\Validation\ValidationException
  • Exception

这很好。我也意识到一个控制路线尝试次数的节流机制。所以邮差我攻击我的路线http://localhost:8000/api/user,直到我得到too many attemp错误。

异常被扔位于文件中:

/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php 

而且我也设法得到异常的类型,它抛出感谢这个forum topicSymfony\Component\HttpKernel\Exception\TooManyRequestsHttpException

所以最终我中间件是这样的:

<?php 

namespace App\Http\Middleware; 

use Closure; 
use Illuminate\Database\Eloquent\ModelNotFoundException; 
use Illuminate\Validation\ValidationException; 
use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException; 
use Exception; 

class ExceptionHandlerMiddleware 
{ 
    public function handle($request, Closure $next) 
    { 
     $output = $next($request); 

     try { 
      if(! is_null($output->exception)) { 
       throw new $output->exception; 
      } 

      return $output; 
     } 
     catch(TooManyRequestsHttpException $e) { 
      return response()->json('this string is never showed up', 429); 
     } 
     catch(ValidationException $e) {   
      return response()->json('validation error' 400); 
     } 
     catch(ModelNotFoundException $e) {    
      return response()->json('not found', 404); 
     } 
     catch(\Exception $e) {    
      return response()->json('unknow', 500); 
     } 
    } 
} 

你看行this string is never showed up?实际上它从来没有出现过,来自Illuminate的原始节气门例外总是占据前面。

问题

我怎样才能正确地重写的方式,我可能(如果可能)捕获任何异常,而无需修改的照射文件(在更新的情况下...)基本误差?

Runing laravel 5.4。

编辑

我不能手动更新app/Http/Exception文件,因为我的应用程序将被运为服务供应商对我的期货其他项目。另外,我不喜欢冒这些风险来清除这些文件的一些以前的配置,因为routes.php中的其他“基本”路由可能有它们自己的异常捕获程序。为实现这一

+0

需要精确版本的Laravel,因为多年来错误处理已经发生了变化。 – Kyslik

+0

您可能需要重新阅读https://laravel.com/docs/5.4/errors#the-exception-handler该部分,如果这不适合您,请返回。 – Kyslik

+0

我看过更新的问题,退一步说如果多个软件包想“处理太多的请求”,Laravel会做什么?那么它会中断,所以你需要在*应用程序级别处理基于HTTP的异常*而不是服务提供者级别,并且不要在中间件中尝试...... catch。一段时间后想想它。“全局”处理程序是唯一的方法,你可以检查请求数据,并确定它是为了“你的软件包”并处理它,如果不是只是重新抛出它。 – Kyslik

回答

0

最好的办法是使用app\Exceptions\Handler.php

public function render($request, Exception $exception) 
{ 
    if ($this->isHttpException($exception)) { 
     if (request()->expectsJson()) { 
      switch ($exception->getStatusCode()) { 
       case 404: 
        return response()->json(['message' => 'Invalid request or url.'], 404); 
        break; 
       case '500': 
        return response()->json(['message' => 'Server error. Please contact admin.'], 500); 
        break; 

       default: 
        return $this->renderHttpException($exception); 
        break; 
      } 
     } 
    } else if ($exception instanceof ModelNotFoundException) { 
     if (request()->expectsJson()) { 
      return response()->json(['message' =>$exception->getMessage()], 404); 
     } 
    } { 
     return parent::render($request, $exception); 
    } 
    return parent::render($request, $exception); 
} 

在本演示中,你可以添加更多的例外像} else if ($exception instanceof ModelNotFoundException) {和解决这些问题。

+0

不幸的是,这意味着即使位于'routes.php'中的“基本”路线也会受到影响,而不仅仅是API,这对我来说是一个问题。 –