Skip to content

fpiardi/MovieApp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 

Repository files navigation

Movies App

This is a movie / tv series app using Offline-First / Single-Source Of Truth (SSOT) Architecture with Clean Architecture:

Screenshots and App Animations

Credits

Nice Error Handling mechanism

Presented by Philipp Lackner is this video

Error handling crossing layers, with Result interface defined in domain module as following:

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

    data class Error<out D, out E : RootError>(
        val error: E,
    ) : Result<D, E>

    data class Loading<out D, out E : RootError>(
        val isLoading: Boolean,
    ) : Result<D, E>
}

Defining Error interface that can be implemented in different layers like:

sealed interface Error
  • DataError, NetworkError enum that describes each errors and can be mapped and properly show to the user in presentation layer
sealed interface DataError : Error {
    enum class Network : DataError {
        BAD_REQUEST,
        FORBIDDEN,
        REQUEST_TIMEOUT,
        INTERNAL_SERVER_ERROR,
        SERVICE_UNAVAILABLE,
        NO_INTERNET,
        UNKNOWN,
    }
}

In Presentation layer, implement asUiText extension function for each new ErrorType and map it to the correct description, according the user language.

fun DataError.asUiText(): UiText =
    when (this) {
        DataError.Network.BAD_REQUEST ->
            UiText.StringResource(
                R.string.data_error_network_bad_request,
            )
        DataError.Network.FORBIDDEN ->
            UiText.StringResource(
                R.string.data_error_network_forbidden,
            )
    }

Simplify the error handling in ViewModel

movieDetailsUseCase(movieId, language, countryCode)
  .onEach { result ->
    when (result) {
      is Result.Error -> {
        _movieDetailsState.update {
          AppState(error = result.error.asUiText())
        }
      }

      is Result.Loading -> {
        _movieDetailsState.update { AppState(isLoading = result.isLoading) }
      }

      is Result.Success -> {
        _movieDetailsState.update { AppState(data = result.data) }
      }
    }
  }.launchIn(viewModelScope)

About

Jetpack Compose project to show and search info about movies

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors