How to catch PostTooLargeException in Laravel?

不打扰是莪最后的温柔 提交于 2021-02-17 02:29:47

问题


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,
  1. 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']);
     }
    
  2. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!