Skip to content

chore: handle goals saving errors#628

Merged
LucasCharrier merged 3 commits intomasterfrom
task/better-goals-handling
Nov 20, 2025
Merged

chore: handle goals saving errors#628
LucasCharrier merged 3 commits intomasterfrom
task/better-goals-handling

Conversation

@LucasCharrier
Copy link
Contributor

No description provided.

@revu-bot revu-bot bot requested a review from revu-bot November 20, 2025 13:36
Copy link
Collaborator

@revu-bot revu-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

This PR adds comprehensive error handling for goals saving operations, distinguishing between local storage errors and API synchronization failures. The implementation provides appropriate user feedback for different failure scenarios.

Key Changes

  • ✅ Added try-catch blocks to handle errors during goal saving
  • ✅ Separated local storage operations from API synchronization
  • ✅ Implemented user-friendly error messages with Alert dialogs
  • ⚠️ 3 Important Issues Found requiring attention

Issues by Severity

Severity Count Category
IMPORTANT 2 Error handling logic
MINOR 1 Type safety

The error handling strategy is sound, but there are issues with the API error detection logic and potential race conditions that need to be addressed.

Comment on lines +83 to +88
// Gestion de la synchronisation API séparément
let apiError = false;
try {
const apiResult = await updateApiReminer(goal);
apiError = !apiResult || apiResult.ok === false || apiResult.error;
} catch (apiErr) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[IMPORTANT] Incorrect API error detection logic

Why it matters:

  • The condition !apiResult will be true when apiResult = { ok: true }, incorrectly flagging success as an error
  • This causes false positives where successful API calls trigger the "not synchronized" warning
  • Users will see unnecessary warning messages even when everything works correctly

Root cause:
The logic checks !apiResult which is falsy for valid success objects. The function updateApiReminer always returns an object, never null/undefined.

Proposed fix:

Suggested change
// Gestion de la synchronisation API séparément
let apiError = false;
try {
const apiResult = await updateApiReminer(goal);
apiError = !apiResult || apiResult.ok === false || apiResult.error;
} catch (apiErr) {
let apiError = false;
try {
const apiResult = await updateApiReminer(goal);
apiError = apiResult?.ok === false || !!apiResult?.error;
} catch (apiErr) {

This correctly identifies errors only when ok is explicitly false or when an error property exists.

Suggested change
// Gestion de la synchronisation API séparément
let apiError = false;
try {
const apiResult = await updateApiReminer(goal);
apiError = !apiResult || apiResult.ok === false || apiResult.error;
} catch (apiErr) {
// Gestion de la synchronisation API séparément
let apiError = false;
try {
const apiResult = await updateApiReminer(goal);
apiError = apiResult?.ok === false || !!apiResult?.error;
} catch (apiErr) {

Comment on lines +97 to 106
// Feedback utilisateur approprié
if (hasApiError) {
Alert.alert(
"Objectifs sauvegardés",
"Vos objectifs ont été sauvegardés localement, mais les rappels n'ont pas pu être synchronisés. Ils seront synchronisés automatiquement lors de votre prochaine connexion.",
[{ text: "OK", onPress: () => navigation.goBack() }]
);
} else {
navigation.goBack();
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[IMPORTANT] Race condition with navigation after Alert dismissal

Why it matters:

  • The Alert's onPress callback navigates back, but the code also calls navigation.goBack() immediately after for the success case
  • If the user dismisses the alert quickly, there could be a double navigation attempt
  • The loading state is reset in finally, but navigation happens asynchronously via Alert callback

Proposed fix:
Move the navigation call outside the Alert to ensure consistent behavior:

Suggested change
// Feedback utilisateur approprié
if (hasApiError) {
Alert.alert(
"Objectifs sauvegardés",
"Vos objectifs ont été sauvegardés localement, mais les rappels n'ont pas pu être synchronisés. Ils seront synchronisés automatiquement lors de votre prochaine connexion.",
[{ text: "OK", onPress: () => navigation.goBack() }]
);
} else {
navigation.goBack();
}
// Feedback utilisateur approprié
if (hasApiError) {
Alert.alert(
"Objectifs sauvegardés",
"Vos objectifs ont été sauvegardés localement, mais les rappels n'ont pas pu être synchronisés. Ils seront synchronisés automatiquement lors de votre prochaine connexion.",
[{ text: "OK" }]
);
}
// Navigate back after showing feedback
navigation.goBack();

This ensures navigation happens consistently regardless of the alert, and the alert is just informational.

Suggested change
// Feedback utilisateur approprié
if (hasApiError) {
Alert.alert(
"Objectifs sauvegardés",
"Vos objectifs ont été sauvegardés localement, mais les rappels n'ont pas pu être synchronisés. Ils seront synchronisés automatiquement lors de votre prochaine connexion.",
[{ text: "OK", onPress: () => navigation.goBack() }]
);
} else {
navigation.goBack();
}
// Feedback utilisateur approprié
if (hasApiError) {
Alert.alert(
"Objectifs sauvegardés",
"Vos objectifs ont été sauvegardés localement, mais les rappels n'ont pas pu être synchronisés. Ils seront synchronisés automatiquement lors de votre prochaine connexion.",
[{ text: "OK" }]
);
}
// Navigate back after showing feedback
navigation.goBack();

Co-authored-by: Revu <dnum.fabrique@sg.social.gouv.fr>
@sonarqubecloud
Copy link

@LucasCharrier LucasCharrier merged commit b03b921 into master Nov 20, 2025
7 of 10 checks passed
@LucasCharrier LucasCharrier deleted the task/better-goals-handling branch November 20, 2025 14:51
@tokenbureau
Copy link

tokenbureau bot commented Nov 20, 2025

🎉 This PR is included in version 1.126.2 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

@tokenbureau tokenbureau bot added the released label Nov 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants