簡介

程式碼範例

基本元件

Error.kt

interface Error

這是一個基礎的介面,方便做為其錯誤的擴充基礎

DataError.kt

sealed interface DataError: Error {

    enum class Network: DataError {
        REQUEST_TIMEOUT,
        UNAUTHORIZED,
        CONFLICT,
        TOO_MANY_REQUESTS,
        NO_INTERNET,
        PAYLOAD_TOO_LARGE,
        SERVER_ERROR,
        SERIALIZATION,
        UNKNOWN
    }

    enum class Local: DataError {
        DISK_FULL
    }
}

這裏以網路 API 常見的錯誤為例

Result.kt

sealed interface Result<out D, out E: Error> {
    data class Success<out D>(val data: D) : Result<D, Nothing>

    data class Error<out E: app.kirin.util.Error>(val error: E) : Result<Nothing, E>
}

inline fun <T, E: Error, R> Result<T, E>.map(map: (T) -> R): Result<R,E> {
    return when(this) {
        is Result.Error -> Result.Error(error)
        is Result.Success -> Result.Success(map(data))
    }
}

fun <T, E: Error> Result<T, E>.asEmptyResult(): EmptyResult<E> {
    return map { }
}

typealias  EmptyResult<E> = Result<Unit, E>

實際使用範例

LoginViewModel.kt

class LoginViewModel(
    private val authRepository: AuthRepository
): ViewModel() {

    ...

    private fun login() {
        viewModelScope.launch {
            ...
            
            val result = authRepository.login(
                email = state.email.text.toString().trim(),
                password = state.password.text.toString()
            )

            when(result) {
                is Result.Error -> {
                    if(result.error == DataError.Network.UNAUTHORIZED) {
                        // 登入不成功,可能是帳密不符
                    } else {
                        // 登入不成功: 其他原因
                    }
                }
                is Result.Success -> {
                    // 登入成功
                }
            }
        }
    }

}

參考資料

This Is My FAVORITE Error Handling Class – by Philipp

How to handle network errors with Ktor

Last modified: 2025 年 7 月 16 日

Author

Comments

Write a Reply or Comment

Your email address will not be published.