security: sanitize all error messages shown to users

Created centralized userFriendlyError() utility that converts raw
exceptions into clean, user-friendly messages. Strips hostnames,
ports, OS error codes, HTTP status codes, stack traces, and Django
field names. Maps network/timeout/auth/server errors to plain
English messages.

Fixed 16 locations across 10 files:
- home_screen, calendar_screen, learn_more_screen (SnackBar/Text)
- login_screen, desktop_login_screen (SnackBar)
- profile_screen, contribute_screen, search_screen (SnackBar)
- review_form, review_section (inline error text)
- gamification_provider (error field)

Also removed double-wrapped exceptions in ReviewService (rethrow
instead of throw Exception('Failed to...: $e')).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-31 07:15:02 +05:30
parent 81872070e4
commit bc12fe70aa
13 changed files with 111 additions and 27 deletions

View File

@@ -53,8 +53,8 @@ class ReviewService {
page: (res['page'] as num?)?.toInt() ?? page,
pageSize: (res['page_size'] as num?)?.toInt() ?? pageSize,
);
} catch (e) {
throw Exception('Failed to load reviews: $e');
} catch (_) {
rethrow;
}
}
@@ -70,8 +70,8 @@ class ReviewService {
},
requiresAuth: true,
);
} catch (e) {
throw Exception('Failed to submit review: $e');
} catch (_) {
rethrow;
}
}
@@ -84,8 +84,8 @@ class ReviewService {
requiresAuth: true,
);
return (res['helpful_count'] as num?)?.toInt() ?? 0;
} catch (e) {
throw Exception('Failed to mark review as helpful: $e');
} catch (_) {
rethrow;
}
}
@@ -97,8 +97,8 @@ class ReviewService {
body: {'review_id': reviewId},
requiresAuth: true,
);
} catch (e) {
throw Exception('Failed to flag review: $e');
} catch (_) {
rethrow;
}
}
}