Laravel使用Service-Repository模式新增数据库记录时如何正确处理异常
现有代码问题梳理
- Repository层
create_new_user方法声明返回bool类型,但实际没有任何return语句,执行后始终返回null,导致控制器判断永远不成立 - Service层
register_user方法没有返回值,无法将Repository的执行结果传递给控制器 - 密码未加密就直接传入存储逻辑,会导致明文密码存入数据库,存在严重安全隐患
- 异常捕获后仅做事务回滚,没有传递错误信息,上层无法感知失败原因
- Service层调用Repository的属性名拼写错误:
userRepositor应为userRepository - 控制器失败分支的提示文案与成功分支相同,属于逻辑错误
代码修复步骤
1. 修正Repository层逻辑
修改create_new_user方法,返回执行状态和错误信息:
use Illuminate\Database\UniqueConstraintViolationException; public function create_new_user(Array $attributes) : array { DB::beginTransaction(); try { User::create($attributes); DB::commit(); return [ 'status' => true, 'message' => '' ]; } catch (UniqueConstraintViolationException $e) { DB::rollBack(); return [ 'status' => false, 'message' => '该邮箱已被注册' ]; } catch (\Exception $e) { DB::rollBack(); return [ 'status' => false, 'message' => '注册失败,请稍后重试' ]; } }
2. 修正Service层逻辑
补全密码加密、缺失字段,返回Repository执行结果:
public function register_user($email, $password, $firstname, $lastname, $role = 'student') { $user_attributes = [ 'email' => $email, 'password' => bcrypt($password), // 密码加密 'name' => $firstname, 'surname' => $lastname, 'role' => $role // 补全角色字段 ]; // 修正拼写错误的属性名 return $this->userRepository->create_new_user($user_attributes); }
3. 修正Controller层逻辑
接收返回结果,将错误信息存入session:
// 验证请求 $request->validated(); // 执行注册逻辑 $registerResult = $this->loginService->register_user( $request->get('email'), $request->get('password'), $request->get('name'), $request->get('surname') ); if ($registerResult['status']) { return redirect("/login")->withSuccess('注册成功'); } else { // 将错误信息存入错误包 return redirect("/register")->withErrors(['register' => $registerResult['message']]); }
视图层展示错误信息
在注册页面的blade模板中,加入错误展示代码即可:
{{-- 展示注册错误 --}} @error('register') <div class="alert alert-danger mt-2"> {{ $message }} </div> @enderror
额外优化建议
可以在请求验证规则中新增邮箱唯一性校验,提前拦截重复请求,减少数据库操作:
// 对应的FormRequest类中补充规则 public function rules() { return [ 'email' => 'required|email|unique:users,email', 'password' => 'required|min:6', 'name' => 'required|string|max:255', 'surname' => 'required|string|max:255', ]; }
内容的提问来源于stack exchange,提问作者Young L.
相关产品推荐
相关产品推荐

