问题
To reproduce the error, simply upload a file(s) to any POST routes in Laravel that exceeds the post_max_size
in your php.ini
configuration.
My goal is to simply catch the error so I can inform the user that the file(s) he uploaded is too large. Say:
public function postUploadAvatar(Request $request)
try {
// Do something with $request->get('avatar')
// Maybe validate file, store, whatever.
} catch (PostTooLargeException $e) {
return 'File too large!';
}
}
The above code is in standard Laravel 5 (PSR-7). The problem with it is that the function can't execute once an error occurs on the injected request. Thereby can't catch it inside the function. So how to catch it then?
回答1:
Laravel uses its ValidatePostSize
middleware to check the post_max_size
of the request and then throws the PostTooLargeException
if the CONTENT_LENGTH
of the request is too big. This means that the exception if thrown way before it even gets to your controller.
What you can do is use the render()
method in your App\Exceptions\Handler
e.g.
public function render($request, Exception $exception)
{
if ($exception instanceof PostTooLargeException) {
return response('File too large!', 422);
}
return parent::render($request, $exception);
}
Please note that you have to return a response from this method, you can't just return a string like you can from a controller method.
The above response is to replicate the return 'File too large!';
you have in the example in your question, you can obviously change this to be something else.
Hope this helps!
回答2:
You can also redirect to a Laravel view of your choice if you wish to add a more content richer response to the user.
public function render($request, Exception $exception)
{
if ($exception instanceof \Illuminate\Http\Exceptions\PostTooLargeException)
return response()->view('errors.post-too-large');
return parent::render($request, $exception);
}
ALSO NOTE:
For the exception to be caught you should make sure you provide the proper path to the PostTooLargeException
by either importing the class using the use Illuminate\Http\Exceptions\PostTooLargeException;
import statement or just writing the full path like in my example.
回答3:
The exception is rendered before the Session starts so you cannot redirect back with an error message.
You can create a new blade file and redirect there like this:
public function render($request, Throwable $exception)
{
if ($exception instanceof \Illuminate\Http\Exceptions\PostTooLargeException) {
return $this->showCustomErrorPage();
}
return parent::render($request, $exception);
}
protected function showCustomErrorPage()
{
return view('errors.errors_page');
//you can also return a response like: "return response('File too large!', 422);"
}
To show a static message using sessions:
1.You have to move the ValidatePostSize
class from the middleware
array into the middlewareGroups
array, directly after the StartSession
.
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
After that in
Handler.php
you can do:public function render($request, Throwable $exception) { if ($exception instanceof \Illuminate\Http\Exceptions\PostTooLargeException) { return $this->showCustomErrorPage(); } return parent::render($request, $exception); } protected function showCustomErrorPage() { return \Illuminate\Support\Facades\Redirect::back()->withErrors(['max_upload' => 'The Message']); }
Show the message on your controller like this:
@error('max_upload') <div class="alert" id="create-news-alert-image">{{ $message }}</div> @enderror
来源:https://stackoverflow.com/questions/42883154/how-to-catch-posttoolargeexception-in-laravel