在Laravel中创建记录时捕获错误的最佳方法

时间:2018-04-07 07:38:53

标签: laravel laravel-5

我有下面的代码,它在job_titles表中插入记录,工作得很好。我在故障情况下使用了该代码的双重检查(Try / Catch和If Statement)。我需要知道它是真的需要还是只有一种方法就足够了。如果只有一种方法就足够了,我应该使用哪种方法。

public function store(Request $request)
    {

        try {
            $rules = [
                'code' => 'required | max:4 | unique:job_titles,code',
                'title' => 'required',
                'description' => 'required'
            ];

            $validated = Validator::make($request->all(), $rules);


            if ($validated->fails()) {
                return response()->json(['status' => 'error', 'message' => 'Please correct validation errors', 'errors' => $validated->errors()]);
            }

            $newJobTitle = JobTitle::create([
                'title' => $request->get('title'),
                'code' => strtoupper($request->get('code')),
                'description' => $request->get('description')
            ]);
            if (!$newJobTitle) {
                return response()->json(['status' => 'error', 'message' => 'Something went wrong!!']);
            }

            return response()->json([
                'status' => 'success',
                'message' => 'Job Title ' . $request->get('title') . ' created successfully'
            ]);
        } catch (\Exception $e) {
            return response()->json(['status' => 'error', 'message' => 'Something went wrong!!', 'exception_message' => $e]);
        }

    }

我在这些之间感到困惑:

try{
}catch(Exception e)
{
}

 $newJobTitle = JobTitle::create([
                'title' => $request->get('title'),
                'code' => strtoupper($request->get('code')),
                'description' => $request->get('description')
            ]);
            if (!$newJobTitle) {
                return response()->json(['status' => 'error', 'message' => 'Something went wrong!!']);
            }

Both the above option

3 个答案:

答案 0 :(得分:1)

通常,在使用数据库时使用try / catch块是一个很好的做法,这样您就可以处理异常,例如:

  • 完整性约束违规
  • 唯一约束
  • ...

并返回最终用户可以理解的良好响应,例如电子邮件已存在,而非出错

让我们举一个注册场景的例子:

如果你有一个User表,它的结构如下所示: id(AI),电子邮件(UNIQUE),密码

user1尝试使用电子邮件user1@gmail.com注册,一切正常,但当另一个用户尝试使用同一封电子邮件注册时,您的查询最终会出现针对电子邮件列的唯一约束违规行为,并尝试抓住您确切知道那里发生了什么。

所以如果你使用第二种方法:

    if (!$newJobTitle) {
        return response()->json(['status' => 'error', 'message' => 'Something went wrong!!']);
    }

你不知道发生了什么。

提示:您不需要将所有代码都包装在try / catch中。

这应该足够了:

try{
$newJobTitle = JobTitle::create([
                'title' => $request->get('title'),
                'code' => strtoupper($request->get('code')),
                'description' => $request->get('description')
            ]);
}catch(\Exception $e) {
}

答案 1 :(得分:1)

这就是我要做的事情:

$rules = [
   'code' => 'required | max:4 | unique:job_titles,code',
   'title' => 'required',
   'description' => 'required'
];
$this->validate($request, $rules);
$newJobTitle = JobTitle::create([
       'title' => $request->get('title'),
      'code' => strtoupper($request->get('code')),
      'description' => $request->get('description')
]);
return response()->json([
        'status' => 'success',
        'message' => 'Job Title ' . $request->get('title') . ' created successfully'
]);

就是这样。如果验证失败,框架将抛出​​验证异常,如果请求是通过AJAX完成的,则转换为传递给视图的错误的重定向响应或JSON错误响应。

这应该足够了。请注意,我没有将整个东西包装在try catch中。只包装部件并在try catch中捕获您可以处理的异常。捕获所有内容只是为了返回一个通用的“oops”消息是没有意义和杂乱的,因为你可以通过一般的异常处理程序方法和/或关闭函数实现相同,Laravel也有这样做,你不需要做任何事情,除了自定义你errors.500 view。

答案 2 :(得分:0)

try/catch将为您提供更精细的控制,以便对如何对抛出的特定异常作出反应。但是,比较真实值并不会执行Exception,因此您可以看到最终需要报告错误的冗余。如果没有$newJobTitle,您可以在此处抛出异常,而不是返回响应:

if (! $newJobTitle) {
    throw new Exception('Job title does not exist');
}

现在,当您退回邮件时,您可以使用$e->getMessage()

return response()->json(['status' => 'error', 'message' => $e->getMessage()]);

但是,您可以拥有自己的自定义异常,例如JobTitleMissingException

现在您可以抛出JobTitleMissingException并专门捕获该异常,因此您可以返回不同的错误代码,例如:

catch(JobTitleMissingException $e) {
    return response()->json(['status' => 'error-job-title', 'message' => $e->getMessage()]);
} catch (\Exception $e) {
    return response()->json(['status' => 'error', 'message' => $e->getMessage()]);
}