如何在中间件 Laravel 5 中捕获“太多尝试”异常
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/45419193/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to catch "too many attempt" exception in a middleware Laravel 5
提问by Anwar
I am building my API and I successfuly managed to catch some errors on a middleware I set up around my routes like following :
我正在构建我的 API 并且我成功地在我围绕我的路由设置的中间件上捕获了一些错误,如下所示:
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');
});
The middleware manage to catch the following exceptions :
中间件设法捕获以下异常:
Illuminate\Database\Eloquent\ModelNotFoundException
Illuminate\Validation\ValidationException
Exception
Illuminate\Database\Eloquent\ModelNotFoundException
Illuminate\Validation\ValidationException
Exception
Which is great. I am also aware of a throttle mecanism that control the number of attempt in a route. So with postman I attacked my route http://localhost:8000/api/user
until I get the too many attemp
error.
这很棒。我还知道控制路线尝试次数的油门机制。因此,与邮递员一起,我攻击了我的路线,http://localhost:8000/api/user
直到too many attemp
出现错误为止。
The exception is throwed in the file located at :
异常在位于以下位置的文件中抛出:
/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php
And I also managed to get the type of exception it throws thanks to this forum topic: Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException
.
由于这个论坛主题,我还设法获得了它抛出的异常类型:Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException
。
So in the end my middleware looks like this :
所以最后我的中间件看起来像这样:
<?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);
}
}
}
You see the line this string is never showed up
? In fact it is never showed up, the original throttle exception from Illuminate always take the front.
你看到这条线了this string is never showed up
吗?事实上它从来没有出现过,来自Illuminate的原始油门例外总是走在前面。
QUESTION
题
How can I properly override the base error in a way that I could possibly (if possible) catch any exception without having to modify the illuminate file (in case of updates...) ?
如何以一种我可能(如果可能)捕获任何异常而无需修改照明文件(在更新的情况下...)的方式正确覆盖基本错误?
Runing laravel 5.4.
运行 Laravel 5.4。
EDIT
编辑
I cannot afford manually updating app/Http/Exception
files because my app will be shipped as a Service Provider for my futures others project. Also, I do not prefer taking the risk to erase some previous configuration on these files, as other "basic" routes in routes.php
may have their own exception catching procedures.
我无法承担手动更新app/Http/Exception
文件的费用,因为我的应用程序将作为我的期货其他项目的服务提供商提供。此外,我不喜欢冒险删除这些文件上的一些先前配置,因为其他“基本”路由routes.php
可能有自己的异常捕获程序。
回答by Kevin Patel
Best way to achieve that is to use app\Exceptions\Handler.php
实现这一目标的最佳方法是使用 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);
}
In this demo you can add more Exception like } else if ($exception instanceof ModelNotFoundException) {
and tackle them.
在这个演示中,您可以添加更多类似的异常} else if ($exception instanceof ModelNotFoundException) {
并解决它们。