Files
iptv-android-tv-hermes/docs/ERROR-HANDLING.md
T

5.9 KiB

Gestion d'erreurs — iMedia TV+

Architecture

flowchart TB
    API[Serveur Xtream] -->|Timeout / 4xx / 5xx| Interceptor[OkHttp ErrorInterceptor]
    Interceptor -->|Exception typée| Repository
    Repository -->|Result / UiState.Error| ViewModel
    ViewModel -->|Message localisé| UI[Écran Compose]
    UI -->|Snackbar / Toast / Overlay| User[Utilisateur]

Hiérarchie d'erreurs

/**
 * Toutes les erreurs Xtream sont des sealed classes
 * pour un `when` exhaustif dans l'UI.
 */
sealed class XtreamException(message: String, cause: Throwable? = null) : Exception(message, cause) {
    class NetworkException(message: String) : XtreamException(message)
    class TimeoutException(message: String) : XtreamException(message)
    class AuthException(message: String) : XtreamException(message)
    class ServerException(val code: Int, message: String) : XtreamException(message)
    class ParseException(message: String, cause: Throwable) : XtreamException(message, cause)
    class StreamUnavailableException(message: String) : XtreamException(message)
}

Table des erreurs

N° Condition Exception Code UI Message FR Message EN
1 Serveur injoignable NetworkException Erreur réseau "Impossible de se connecter au serveur. Vérifiez votre réseau." "Cannot reach server. Check your network."
2 Timeout dépassé (15s) TimeoutException Erreur réseau "Le serveur ne répond pas. Réessayez plus tard." "Server is not responding. Try again later."
3 Auth invalide AuthException Login bloqué "Identifiants incorrects ou serveur invalide." "Invalid credentials or server."
4 Flux vidéo cassé StreamUnavailableException Overlay erreur "Flux indisponible pour cette chaîne." "Stream unavailable for this channel."
5 HTTP 4xx ServerException Toast "Erreur serveur (code X). Contactez votre fournisseur." "Server error (code X). Contact your provider."
6 HTTP 5xx ServerException Toast "Le serveur Xtream rencontre un problème." "Xtream server is having issues."
7 JSON mal formé ParseException Fallback silencieux "Données reçues incorrectes." "Received data is malformed."
8 EPG vide N/A (pas une erreur) Texte vide "Aucun programme trouvé pour cette chaîne." "No program found for this channel."
9 Cache corrompu N/A Suppression + reload "Mise à jour des données..." "Updating data..."

État loading global

/**
 * État unique pour TOUS les écrans.
 * Permet un traitement uniforme dans les composants UI.
 */
sealed interface UiState<out T> {
    data object Idle : UiState<Nothing>
    data object Loading : UiState<Nothing>
    data class Success<T>(val data: T) : UiState<T>
    data class Error(
        val message: String,              // Message affiché à l'utilisateur
        val retry: Boolean = true,        // Afficher un bouton "Réessayer" ?
        val exception: XtreamException? = null // Pour logging uniquement
    ) : UiState<Nothing>
}

Intercepteur OkHttp

class XtreamErrorInterceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()
        return try {
            val response = chain.proceed(request)
            if (!response.isSuccessful) {
                when (response.code) {
                    401, 403 -> throw XtreamException.AuthException(
                        "Authentication failed"
                    )
                    in 400..499 -> throw XtreamException.ServerException(
                        response.code, "Client error"
                    )
                    in 500..599 -> throw XtreamException.ServerException(
                        response.code, "Server error"
                    )
                }
            }
            response
        } catch (e: SocketTimeoutException) {
            throw XtreamException.TimeoutException("Connection timed out")
        } catch (e: ConnectException) {
            throw XtreamException.NetworkException("Cannot connect")
        } catch (e: UnknownHostException) {
            throw XtreamException.NetworkException("DNS resolution failed")
        }
    }
}

Comportement UI par erreur

Écran de connexion

[Champs vides]
❌ Bouton Connexion désactivé

[Erreur réseau]
✅ Bouton actif, message rouge sous le formulaire
✅ Champs conservés (pas de reset)

[Auth refusée]
✅ Message : "Identifiants incorrects"
✅ Focus revient sur le champ mot de passe

Écran Live TV

[Erreur chargement chaînes]
✅ Toast 3s : "Impossible de charger les chaînes"
✅ Cache affiché si disponible

[Chaîne sans flux]
✅ Overlay : "Flux indisponible" + bouton "Chaîne suivante"

Lecteur vidéo

[Flux mort pendant lecture]
✅ Remplacer par écran noir + message
✅ Bouton "Chaîne suivante" visible
✅ Retour possible vers le menu

Règles de logging

Niveau Usage Exemple
Timber.d Debug uniquement (pas en prod) "Loading 42 live channels"
Timber.i Événements importants "User logged in: user123"
Timber.w Anomalies non bloquantes "EPG cache expired for stream 99"
Timber.e Erreurs utilisateur "Stream unavailable for stream 42"

❌ Interdit : Log.d("PASSWORD", password) ou tout log contenant des credentials.

Annexes

Codes Xtream que l'on peut rencontrer

Code Signification Action
auth = "0" Compte invalide Message login
status = "Expired" Abonnement expiré Message distinct
status = "Disabled" Compte désactivé Message distinct
tv_archive = 0 Pas d'archive Cacher bouton Replay
has_archive = false Pas d'archive Cacher bouton Replay
Réponse vide Serveur HS ou mauvaise URL Erreur réseau générique