일정관리앱서버의 두 번째 트러블슈팅은 로그인시 이메일이나 비밀번호를 잘못 입력 시 401 UNAUTHORIZED
가 뜨는 게 아니라 500 INTERNAL SERVER ERROR
가 뜨는 현상에 대해 다루어보았다.
- 회원가입 기능 : username, email, password를 입력하여 유저 정보 생성 (사용자 id 자동 생성)
- 로그인 기능 : email과 password를 통해 사용자 인증을 하여 세션을 생성
- 필터 기능 : 회원가입과 로그인 기능을 제외한 기능들은 모두 세션이 있어야 정상적으로 작동
- 유저 조회, 삭제 기능
- 일정 생성 : 세션의 사용자 userId로 일정을 생성
- 일정 전체 조회 : 세션의 사용자가 작성한 일정을 전체 조회
- 일정 단건 조회, 수정, 삭제 : 일정의 id(pk)를 path로 받아 조회, 수정, 삭제
로그인 기능을 테스트하던 중 이메일이나 비밀번호를 잘못 입력하였을 때 401 UNAUTHORIZED
이 아니라 500 INTERNAL SERVER ERROR
이 뜨는 것을 발견하였다.
로그인 기능을 구현한 방식은 다음과 같았다.
LoginRequestdto로 email과 password를 받아 repository 영역에서 db에 두 값이 일치하는 user를 찾고 그 id를 get 한다.
그리고 그 id가 null일 경우 401을 띄우는 방법으로 예외처리를 한다.
id를 가져오는 이유는 로그인 후 생성될 세션이 사용할 것은 user의 id밖에 없다고 보았고 service와 controller 사이에 dto 형식으로 데이터를 주고받기 위해 id를 매개변수로 생성한 LoginResponseDto를 controller로 전달하는 것이었다.
이메일이나 비밀번호를 잘못 입력한 경우, service
에서는 해당하는 List<User>
를 찾지 못해 내용이 빌 것이고
이 때 .stream()
으로 내용물을 찾아도 null
이 뜨게 될 것이다. 그러면 .getId()
로 받아온 Long userId
도 null
이 되어 나가 controller
영역에서 예외처리가 날 것이라고 생각하였다.
다만 이 과정에서 .orElse(null)
뒤에 .getId()
가 붙어 null
을 직접적으로 get
하게 되었고 여기서 500 INTERNAL SERVER ERROR
이 뜬 것이었다.
해결을 위해 null
인지 아닌지를 먼저 확인하고 예외처리 후, null
이 아닐 때만 get
을 해올 수 있도록 수정해주기로 했다. 따로 if문 처리를 할까 하다가 어처피 .orElse()
를 붙이고 있기 때문에 이를 .orElseThorw()
로 예외처리를 바로 해주고 뒤에 .get()
을 붙여주기로 했다.
등록된 유저를 찾는 과정에서 이메일이나 비밀번호를 잘못 입력시null
을 get
하는 문제때문에 500 INTERNAL SERVER ERROR
가 떴기때문에 null
을 잡지 않도록 미리 예외처리를 해주어서 해결했다.
get
으로 null
을 잡고 이를 Long
같은 데이터타입에 담으려고 할 경우 500 에러가 날 수 있다는 것을 이 기회에 알게 되었다. 다음에는 이런 일이 발생하지 않도록 미리 예외처리로 날려 깔끔하게 코드를 작성할 수 있도록 하겠다.