Aller au contenu principal

Guide de dépannage (Troubleshooting)

Cette page recense les problèmes les plus fréquents rencontrés lors de l'intégration ou de l'exploitation du SDK tk_ota_push et du moteur natif, avec leur cause exacte dans le code et la procédure de résolution.

1. Le patch n'est pas téléchargé ou ne s'applique pas​

Symptôme A : TkOtaPush.instance.isAvailable retourne false​

  • Cause : L'application a été lancée en mode Debug (flutter run) ou compilée avec le SDK Flutter standard au lieu de la toolchain Shorebird (tk-ota-push release).
  • Solution : Compilez toujours le binaire de base avec tk-ota-push release et installez l'APK/IPA généré en mode Release.

Symptôme B : outcome.executionMode vaut blockedByGatekeeper (networkCallPerformed: false)​

  • Cause : L'une des 3 conditions cumulatives du RemoteConfigGatekeeper n'est pas remplie. Inspectez outcome.gatekeeperEvaluation?.verdict et outcome.message :
    • GatekeeperVerdict.skippedVersionMismatch : la version passée à TkOtaPush.init(appReleaseVersion: ...) ne correspond pas exactement à target_release_version du JSON Remote Config.
    • GatekeeperVerdict.skippedNoPatchAvailable : patch_available est à false dans le JSON Remote Config.
    • GatekeeperVerdict.skippedAlreadyUpToDate : le numéro de patch déjà installé (currentPatchNumber) est supérieur ou égal à latest_patch_number.
  • Solution : Alignez appReleaseVersion avec la version exacte de pubspec.yaml (ex: '1.0.0+3') et incrémentez latest_patch_number dans votre Remote Config.

Symptôme C : Le patch est téléchargé mais l'interface ne change pas immédiatement​

  • Cause : Par conception, le moteur C++/Rust charge le nouveau snapshot (binaire d'application ou artefact de patch) lors de l'initialisation de la VM Dart au démarrage à froid (Cold Start). Mettre l'application en arrière-plan puis la reprendre (Warm Resume) ne recharge pas la bibliothèque partagée.
  • Solution : Fermez complètement le processus de l'application (ou redémarrez-la après une mise à jour critique où outcome.restartRequired == true).

2. Erreur Update rejected: hash mismatch ou CorruptPatch​

  • Cause : Le binaire binaire d'application (Android) ou App (iOS) installé sur le téléphone ne possède pas la même empreinte SHA-256 que la Release de référence enregistrée sur le serveur OTA. Cela survient si vous avez recompilé l'APK avec flutter build apk après avoir exécuté tk-ota-push release, ou si un ancien fichier intermédiaire non strippé a été utilisé.
  • Solution :
    1. Utilisez tk_ota_push >= 0.5.1 / 1.0.0, où Publisher._extractLibAppFromPackage extrait directement binaire d'application depuis l'archive finale .apk ou .aab.
    2. Distribuez aux utilisateurs exactement le fichier .apk, .aab ou .ipa produit par l'exécution de tk-ota-push release, sans relancer de build manuel postérieur.

3. Erreur InvalidSignature (Patch signature could not be verified)​

  • Cause : Le moteur Rust a rejeté le patch car la signature RSA (hash_signature) renvoyée par POST /api/v1/patches/check ne correspond pas à la clé patch_public_key embarquée dans flutter_assets/shorebird.yaml (catégorie télémétrique failure_category: "invalid_signature").
  • Solution :
    1. Vérifiez que shorebird.yaml est bien déclaré dans la section flutter.assets de pubspec.yaml.
    2. Vérifiez que la clé RSA dans moteur cryptographique n'a pas été recréée sous un autre couple clé privée / clé publique depuis la publication de la Release Store.
    3. Lors de chaque tk-ota-push release, la CLI synchronise automatiquement patch_public_key depuis GET /api/admin/v1/public-key.

4. Crash au démarrage d'un patch (Bootloop) & Alerte Rollback Actif​

  • Cause : Le code introduit dans le patch provoque une exception fatale dès le démarrage, ou tente de lire un cache local incompatible après une régression de version.
  • Comportement automatique :
    1. Au lancement suivant, handle_prior_boot_failure_if_necessary() détecte que currently_booting_patch n'a pas terminé son amorçage.
    2. Le moteur Rust marque le patch comme PatchKnownBad, restaure la version saine précédente et envoie __patch_install_failure__ (crash_recovery: patch N failed to boot).
    3. Côté Dart, OtaRollbackTracker déclenche onRollbackDetected(OtaRollbackEvent).
  • Solution :
    1. Implémentez le callback onRollbackDetected dans TkOtaPush.init pour purger vos caches locaux (SharedPreferences, SQLite, Hive) en cas de retour arrière.
    2. Corrigez le bug dans votre code Dart et publiez un nouveau patch avec un numéro supérieur (N + 1).
    3. Dans la Console Web (/support), acquittez l'alerte de rollback sur les appareils concernés.

5. app_id incorrect ou conflit entre environnements (dev / staging / prod)​

  • Cause : Les patchs publiés ne remontent pas sur le téléphone car l'app_id embarqué lors de la Release diffère de l'app_id ciblé lors du tk-ota-push patch.
  • Solution :
    1. Vérifiez la cascade de résolution dans FlutterProject.resolveEffectiveAppId : si vous avez compilé la Release avec --flavor prod, passez également --flavor prod lors de la commande tk-ota-push patch.
    2. Vérifiez la valeur effective inscrite en tête de votre shorebird.yaml après le build.

6. Serveur OTA injoignable & Blocage HTTP Cleartext sur Android​

  • Symptôme : Aucune requête n'arrive sur le serveur Serveur TkushPatch (ShorebirdUpdaterController) lorsque vous testez sur un smartphone Android en Wi-Fi local avec base_url: "http://192.168.x.x:8080", et la télémétrie enregistre failure_category: "network".
  • Causes & Solutions :
    1. Permission INTERNET manquante : ajoutez <uses-permission android:name="android.permission.INTERNET"/> dans android/app/src/main/AndroidManifest.xml.
    2. Blocage HTTP Cleartext Android 9+ : pour les tests locaux en http:// (sans TLS), ajoutez android:usesCleartextTraffic="true" sur la balise <application> de votre AndroidManifest.xml.
    3. Utilisation de localhost dans base_url : sur un smartphone physique, localhost désigne le téléphone lui-même et non votre ordinateur. Utilisez l'IP LAN de votre machine dans shorebird.yaml (ex: http://192.168.0.199:8080). Le serveur Serveur TkushPatch réécrira automatiquement les URLs de téléchargement d'artefacts grâce à ShorebirdUpdaterController.resolveClientReachableUrl.

7. Blocage DIVERGENCE DE CODE NATIF DÉTECTÉE lors d'un patch​

  • Symptôme : La commande tk-ota-push patch s'arrête avec le message : DIVERGENCE DE CODE NATIF DÉTECTÉE (classes.dex, manifest ou libs C++ modifiés) (ou Info.plist ou Frameworks modifiés sur iOS).
  • Cause : Le NativeIntegrityScanner a détecté que le code natif compilé (nativeCodeHash) a changé par rapport à la Release verrouillée sur le serveur (ajout d'un plugin Flutter contenant du code Kotlin/Swift/C++ ou modification de AndroidManifest.xml / Info.plist).
  • Solution :
    • Le moteur OTA ne pouvant patcher que la couche Dart, incrémentez la version dans pubspec.yaml et publiez une nouvelle Release Store (tk-ota-push release).
    • Si vous êtes certain que la modification native n'impacte pas l'exécution du code Dart, vous pouvez forcer la publication avec --force (non recommandé en production).

8. Blocage HTTP 409 CONFLICT - PROTECTION CONTRE LE 'RELEASE OVERWRITE'​

  • Symptôme : tk-ota-push release échoue avec une erreur HTTP 409 CONFLICT indiquant que la Release est déjà verrouillée.
  • Cause : La méthode Publisher.guardNoOverwrite interdit d'écraser une Release existante avec un nouveau build, car recompiler sous le même numéro de version modifierait les adresses mémoire du binaire de base et provoquerait des erreurs de segmentation (Segfault) sur les téléphones ayant déjà installé cette Release.
  • Solution :
    • Si vous souhaitez corriger la version déjà en ligne, utilisez tk-ota-push patch.
    • Si vous publiez une nouvelle version sur le Store, incrémentez le numéro de build dans pubspec.yaml (ex: 1.0.0+2 vers 1.0.0+3) avant de lancer tk-ota-push release.