【问题标题】:Is try catch block necessary inside controller in laravel?在 laravel 的控制器内部是否需要 try catch 块?
【发布时间】:2020-02-16 08:00:58
【问题描述】:

我目前正在和我的朋友一起做一个项目。他遵循这种编写代码的方法。是好还是坏?我也不是经验丰富的开发人员。

public function store(Request $request)
 {  
    try   
    {  
        $comment = new TicketComment();  
        $comment->content = $request['comment'];  
        $comment->user_id = Auth::user()->id;  
        $comment->ticket_id = $request['ticketId'];  
        $comment->save();  
        $ticket = Ticket::where('id', '=', $comment->ticket_id)->first();  
        $ticket->updated_at = $comment->created_at;  
        $ticket->update();  
    }    
    catch(Exception $e)  
    {  
        request()->session()->flash('unsuccessMessage', 'Failed to add comment !!!');  
        return redirect()->back();  
    }  
    request()->session()->flash('successMessage', 'Comment has been successfully added !!!');  
    return redirect()->back();  
}  

【问题讨论】:

  • 是的,这里最好有try-catch 屏蔽
  • @Ronak Dhoot 你能解释一下原因吗?
  • 不,您不需要 try-catch 块。正如下面的答案中提到的,Laravel 确实有自己的错误处理系统,因此任何抛出的异常都会被 Laravel 捕获并报告。话虽如此,try-catch 块,在这种情况下,有利于向用户显示更具体的错误,但它会以不记录底层错误的堆栈跟踪为代价。从长远来看,在当前状态下,调试代码会更加困难,因为您会知道出了问题,但您不知道发生了什么。

标签: php laravel exception try-catch


【解决方案1】:

没有广泛的异常捕获块。仅捕获您希望在该块中抛出的异常,这样您就可以正确记录意外异常并修复代码中可能导致这些异常的任何其他错误,而不是对自己隐藏它们。

如果你必须这样做,那么它可能是在这样的上下文中:

public function store(Request $request)
 {  
    try   
    {  
        $comment = new TicketComment();  
        $comment->content = $request['comment'];  
        $comment->user_id = Auth::user()->id;  
        $comment->ticket_id = $request['ticketId'];  
        $comment->save();  
        $ticket = Ticket::where('id', '=', $comment->ticket_id)->first();  
        $ticket->updated_at = $comment->created_at;  
        $ticket->update();  
    }    
    catch(Exception $e)  
    {  
        if (!($e instanceof SQLException)) {
            app()->make(\App\Exceptions\Handler::class)->report($e); // Report the exception if you don't know what actually caused it
        }
        request()->session()->flash('unsuccessMessage', 'Failed to add comment !!!');  
        return redirect()->back();  

    }  
    request()->session()->flash('successMessage', 'Comment has been successfully added !!!');  
    return redirect()->back();  
}  

这样,仍然会报告任何意外异常,您可以稍后查看日志以修复导致它们的任何错误。

提醒一下,自 PHP 7.1 起,您可以在 catch 块 (Reference) 中合并异常,例如

try { } 
catch (ExceptionType1|ExceptionType2 $e) {

}

这样你可以处理你知道可以处理的异常,让 Laravel 处理你不确定如何处理的异常。

请注意,您通常不必在控制器代码中包含 try-catch 块,如果这是您首选的处理方式,您始终可以使用异常处理程序对所有未处理的异常执行闪存/重定向返回组合。

【讨论】:

    【解决方案2】:

    处理错误总是好的。然而,Laravel 内置了错误处理,这简化了这个过程。这并不意味着您不需要 try catch 块。 阅读有关 laravel 错误处理的更多信息:https://laravel.com/docs/5.8/errors

    【讨论】:

    • 我们需要担心控制器冗长吗?
    • 要缩短您的控制器,请创建和使用存储库和服务类。
    【解决方案3】:

    即使 laravel 有他自己的内置错误处理,你最好使用 trycatch。 不要在开发模式下使用它,而是在生产模式下使用它。 try & catch 的使用对用户很友好,这意味着用户不会看到带有 laravel 生成错误的传统页面(如果出现任何错误),但会看到您的默认消息。

    使用示例:

    public function index()
    {
       try {
    
               return view('index.blade.php');
    
       } catch (\Exception $exception) {
    
               \Log::error($exception);
    
               return redirect()->back()->with(['message' => 'There was an error']);
       }
    }
    

    如果你看到这部分\Log::error($exception);,这意味着laravel产生的错误将被记录在storage/logs/laravel.log下的日志文件中,所以你作为开发者可以看到该方法的问题。另一方面,如果访问页面出现问题:view('index.blade.php'),用户将被重定向回上一个页面,并在session 中保存一条消息,即:'There was an error'

    要在刀片出现错误时捕获消息,您应该:

               @if (session('message'))
                <div class="container">
                    <div class="alert alert-danger text-center">{{ session('message') }}</div>
                </div>
                @endif
    

    编码愉快!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-09
      • 1970-01-01
      • 1970-01-01
      • 2018-08-25
      • 1970-01-01
      • 2017-09-30
      相关资源
      最近更新 更多