Repository navigation
fix(mobile): ignorer la vibration refusée sans moteur haptique - #481
Merged
Merged
Conversation
…engine On a Redmi Note 9, every vibration rejected with "A haptics engine is not available on this device": the expo-haptics promises were started with `void` and no catch, so the rejection went unhandled and reached Sentry. Every call now goes through `vibrate`, which drops a rejection, and a synchronous throw of a missing native module, in silence. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Collaborator
Author
|
Plan et décisions : une seule enveloppe |
This was referenced Oct 15, 2026
Open
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Résultat et problème
Sur le Redmi Note 9 (build preview
858b93ac), chaque vibration levait « Call to function 'ExpoHaptics.performHapticsAsync' has been rejected → A haptics engine is not available on this device », remontée à Sentry (WIDOO-MOBILE-W) : dansapps/mobile/src/ui/haptics.ts, les promesses d'expo-hapticsétaient lancées parvoid, sanscatch.Désormais, chaque appel (Android
performAndroidHapticsAsync, iOSselectionAsync,impactAsync,notificationAsync) passe par une enveloppevibratequi ignore en silence le rejet de la promesse, ainsi qu'une exception synchrone (module natif absent du build). Ni erreur, ni rapport Sentry ; le toast ou l'action qui a demandé la vibration se poursuit normalement.hapticreste le seul point d'appel d'expo-hapticsdansapps/mobile/src.Fixes #476
Écrans : aucun
Dépendance : aucune
Comment vérifier
Nouveau test Vitest
apps/mobile/src/ui/haptics.test.ts: les fonctions d'expo-hapticssont remplacées par des fonctions qui rejettent avec le message du Redmi ; il vérifie, sur Android puis sur les trois méthodes iOS, qu'aucununhandledRejectionn'est émis, quehapticne lève rien et queSentry.captureExceptionn'est pas appelé, plus le cas d'un module natif qui lève avant toute promesse. Les mocks sont des fonctions simples, pas desvi.fn: un spy Vitest accroche ses propres handlers à la promesse renvoyée, ce qui masquerait le rejet non géré. Contrôle : les 3 tests échouent sur le code demain, passent avec le correctif.Pas de recette sur appareil : les émulateurs ont un moteur haptique et ne reproduisent pas le refus ; les tests suffisent. Aucun écran touché, donc pas de test à 150 % de texte.
pnpm lint && pnpm typecheck && pnpm testverts en local (mobile : Vitest 386 tests, Jest 191 tests ; Prettier vert)Testé sur iOS / Android (préciser) — sans objet, voir ci-dessus
Formatage mécanique : non
Risque
Niveau : 1 — robustesse d'un module de vibration côté client, aucun effet sur la sécurité, les données ou l'infrastructure.
Taille : 1 commit, 104 lignes ajoutées et 4 supprimées (dont 87 de test).
Revue OWASP : non déclenchée (aucun accès, configuration, dépendance ni journalisation modifiés ; l'erreur ignorée est un refus matériel sans valeur de diagnostic).
Retour arrière
Revert de la PR suffit ; aucune migration, aucune donnée.
🤖 Generated with Claude Code