簡介
程式碼範例
基本元件
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>
實際使用範例 – 1
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 -> {
// 登入成功
}
}
}
}
}實際使用範例 – 2
enum class PasswordValidationError: Error {
TOO_SHORT,
MISSION_ONE_DIGIT
}
fun validatePassword(password: String): Result<Unit, PasswordValidationError> {
// TODO: validation login here
// if error
return Result.Error(PasswordValidationError.MISSION_ONE_DIGIT)
}
fun handleError(result: Result<Unit, PasswordValidationError>) {
when(result) {
is Result.Error -> {
when(result.error) {
PasswordValidationError.TOO_SHORT -> TODO()
PasswordValidationError.MISSION_ONE_DIGIT -> TODO()
}
}
is Result.Success -> {
// TODO: this is a valid password
}
}
}參考資料
This Is My FAVORITE Error Handling Class – by Philipp
Comments