check & require로 예외처리를 간단하게

2024. 7. 15. 21:33TIL

✔오늘 배운 중요한 🔑 point

  • require 함수: 입력 값 검증에 적합하며, 조건이 만족되지 않을 경우 IllegalArgumentException을 던진다
  • check 함수: 코드의 상태를 검증하는 데 적합하며, 조건이 만족되지 않을 경우 IllegalStateException을 던진다.

🎯 오늘 배운 내용

 

check함수

@kotlin.internal.InlineOnly
public inline fun check(value: Boolean): Unit {
    contract {
        returns() implies value
    }
    check(value) { "Check failed." }
}

/**
 * Throws an [IllegalStateException] with the result of calling [lazyMessage] if the [value] is false.
 *
 * @sample samples.misc.Preconditions.failCheckWithLazyMessage
 */
@kotlin.internal.InlineOnly
public inline fun check(value: Boolean, lazyMessage: () -> Any): Unit {
    contract {
        returns() implies value
    }
    if (!value) {
        val message = lazyMessage()
        throw IllegalStateException(message.toString())
    }
}

2개의 함수의 차이는 기본 메시지("Check failed") vs. 사용자 정의 메시지

 

check 함수 활용

기존 코드

override fun login(request: LoginRequest): TokenResponse {
        val loginMember = memberRepository.findByEmail(request.email) ?: throw IllegalArgumentException("잘못된 이메일입니다.")
        require(passwordEncoder.matches(request.password, loginMember.password)) { "잘못된 비밀번호입니다." }

        return TokenResponse(
            accessToken = jwtTokenManager.generateToken(memberId = loginMember.id, memberRole = MemberRole.MEMBER),
            refreshToken = null
        )
    }

변경된 코드

    override fun login(request: LoginRequest): TokenResponse {
        check(initialized) { "MemberServiceImpl is not initialized yet." }
        val loginMember = memberRepository.findByEmail(request.email) ?: throw IllegalArgumentException("잘못된 이메일입니다.")
        require(passwordEncoder.matches(request.password, loginMember.password)) { "잘못된 비밀번호입니다." }

        return TokenResponse(
            accessToken = jwtTokenManager.generateToken(memberId = loginMember.id, memberRole = MemberRole.MEMBER),
            refreshToken = null
        )
    }

 

require 함수

@kotlin.internal.InlineOnly
public inline fun require(value: Boolean): Unit {
    contract {
        returns() implies value
    }
    require(value) { "Failed requirement." }
}

/**
 * Throws an [IllegalArgumentException] with the result of calling [lazyMessage] if the [value] is false.
 *
 * @sample samples.misc.Preconditions.failRequireWithLazyMessage
 */
@kotlin.internal.InlineOnly
public inline fun require(value: Boolean, lazyMessage: () -> Any): Unit {
    contract {
        returns() implies value
    }
    if (!value) {
        val message = lazyMessage()
        throw IllegalArgumentException(message.toString())
    }
}

2개의 함수의 차이는 기본 메시지("Failed requirement.") vs. 사용자 정의 메시지

 

require 함수 활용

기존 코드

override fun login(request: LoginRequest): TokenResponse {

    val loginMember = memberRepository.findByEmail(request.email) ?: throw RuntimeException("잘못된 아이디")
    if (!passwordEncoder.matches(
            request.password,
            loginMember.password
        )
    ) throw RuntimeException("잘못된 비밀번호")
    return TokenResponse(
        accessToken = jwtTokenManager.generateToken(memberId = loginMember.id, memberRole = MemberRole.MEMBER),
        refreshToken = null
    )
}

 

변경된 코드

    override fun login(request: LoginRequest): TokenResponse {
        val loginMember = memberRepository.findByEmail(request.email) ?: throw IllegalArgumentException("잘못된 이메일입니다.")
        require(passwordEncoder.matches(request.password, loginMember.password)) { "잘못된 비밀번호입니다." }

        return TokenResponse(
            accessToken = jwtTokenManager.generateToken(memberId = loginMember.id, memberRole = MemberRole.MEMBER),
            refreshToken = null
        )
    }

 

 

🤔 어떻게 활용할까?

require와 check 함수를 활용하여 코드의 가독성을 더 높일수 있게 되었다.

📓 오늘의 한줄

"The greater the obstacle, the more glory in overcoming it."

- Molière -