Skip to content

fix(mobile): ignorer la vibration refusée sans moteur haptique - #481

Merged
PaulThiberville merged 1 commit into
mainfrom
issue/476-haptics-rejection
Oct 15, 2026
Merged

PaulThiberville merged 1 commit into
mainfrom
issue/476-haptics-rejection

Conversation

@PaulThiberville

Copy link
Copy Markdown
Collaborator

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) : dans apps/mobile/src/ui/haptics.ts, les promesses d'expo-haptics étaient lancées par void, sans catch.

Désormais, chaque appel (Android performAndroidHapticsAsync, iOS selectionAsync, impactAsync, notificationAsync) passe par une enveloppe vibrate qui 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. haptic reste le seul point d'appel d'expo-haptics dans apps/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-haptics sont 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'aucun unhandledRejection n'est émis, que haptic ne lève rien et que Sentry.captureException n'est pas appelé, plus le cas d'un module natif qui lève avant toute promesse. Les mocks sont des fonctions simples, pas des vi.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 de main, 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 test verts 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

…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>
@PaulThiberville

Copy link
Copy Markdown
Collaborator Author

Plan et décisions : une seule enveloppe vibrate(start) dans haptics.ts plutôt qu'un .catch à chaque appel, pour que tout nouvel appel haptique hérite du silence ; elle prend une fonction (et non une promesse) pour couvrir aussi l'exception synchrone d'un module natif absent. Le test utilise des fonctions simples à la place de vi.fn, dont le suivi des résultats marquerait la promesse comme gérée.

@PaulThiberville
PaulThiberville merged commit 4b766c5 into main Oct 15, 2026
4 checks passed
@PaulThiberville
PaulThiberville deleted the issue/476-haptics-rejection branch October 15, 2026 10:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Ignorer l'absence de moteur haptique au lieu de remonter une erreur

1 participant