웹 프로그래밍

[Spring Boot] Licruit - 에러 처리

미안하다 강림이 좀 늦었다 2024. 9. 11. 23:31

 

 

Response

SuccessResponse

express에서 end()와 같은 것이라고 생각하고 있다. 파라미터로 String message를 받으면 모든 Success 응답에서 메시지를 적어줘야 하는데 그래야 할 이유가 없는 것 같아서 파라미터를 받지 않기로 했다.

public record SuccessResponse() { }

 

UserController

회원가입이 정상적으로 이루어졌으면 201을 반환한다. body는 {} 이렇게 응답을 보낸다.

@RestController
@RequestMapping("/users")
@RequiredArgsConstructor
public class UserController {
    private final UserService userService;

    @PostMapping("/register")
    public ResponseEntity<SuccessResponse> addUser(@RequestBody @Valid RegisterRequest registerRequest) {
        userService.createUser(registerRequest);
        return ResponseEntity.status(HttpStatus.CREATED).body(new SuccessResponse());
    }
}

 

 

에러 처리

ErrorResponse

에러일 경우에는 응답에 메시지를 담을 수 있다.

public record ErrorResponse (
        String message
) { }

 

GlobalExceptionHandler

자바에서는 던진 에러의 종류에 따라 에러를 다르게 처리할 수 있는 것 같다. MethodArgumentNotValidException이 유효성 검사 결과 예외에 대한 자료형이다.

이전에 express로 할 때는 중복키에 대한 에러 처리를 400으로 했었는데 검색해 보니까 409가 맞다고 한다.

@RestControllerAdvice
public class GlobalExceptionHandler {

    // 유효성 검사 에러 핸들러
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<ErrorResponse> handleArgumentNotValidException(MethodArgumentNotValidException ex) {
        String message = ex.getBindingResult().getAllErrors().get(0).getDefaultMessage();
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ErrorResponse(message));
    }

    // 중복키 에러 핸들러
    @ExceptionHandler(DuplicateKeyException.class)
    public ResponseEntity<ErrorResponse> handleDuplicateKeyException(DuplicateKeyException ex) {
        ErrorResponse errorResponse = new ErrorResponse(ex.getMessage());
        return ResponseEntity.status(HttpStatus.CONFLICT).body(errorResponse);

    }
}

 

 

기본키 중복 확인

UserRepository

repository에 사업자번호가 존재 여부에 대한 메소드를 적어준다. 접두사 existsBy 이게 약속인 것 같다. 이 함수에 대해 따로 구현하지 않아도 알아서 존재 여부를 boolean으로 반환해 준다.

@Repository
public interface UserRepository extends JpaRepository<UserEntity, String> {
    boolean existsByCompanyNumber(String companyNumber);
}

 

UserService

컨트롤러에서 createUser을 호출하고 있다. 회원가입 할 때 사업자번호가 중복되는지 확인 → 비밀번호 암호화 → DB에 저장 순서로 이루어진다.

@Service
@RequiredArgsConstructor
public class UserService {

    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;

    public void checkCompanyNumberDuplicate(String companyNumber) {
        if(userRepository.existsByCompanyNumber(companyNumber)) {
            throw new DuplicateKeyException("이미 사용된 사업자번호입니다.");
        }
    }

    public void createUser(RegisterRequest registerRequest) {
        checkCompanyNumberDuplicate(registerRequest.getCompanyNumber());
        UserEntity userEntity = UserEntity.toUserEntity(registerRequest);
        userEntity.setPassword(passwordEncoder.encode(userEntity.getPassword()));
        userRepository.save(userEntity);
    }
}

 

내가 참고하고 있는 다른 팀의 코드를 보니까 DuplicateKeyException 에러를 바로 던지지 않고 DuplicateKeyException을 상속받는 UserAlreadyExistException이라는 클래스를 만들어서 에러를 던지고 있었다. 왜.... 그렇게 해야 되는지 잘 모르겠어서 일단 DuplicateKeyException를 던지는 걸로 구현했다.

 

 

주저리

에러 처리랑 응답 어떻게 하는지 알고 나니까 고비 하나 넘긴 기분이다.

비밀번호 변경할 때 set을 쓰는데 이거 쓰면 안 된다고 어디서 들은 것 같은데...... 일단 내버려두기로 했다. 나중에 build로 고쳐야겠다.

내일은 로그인이랑 jwt 해보기~~