From f2f596dc70756402fd27edea69cfd399dd39b183 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Wed, 20 May 2026 07:53:14 +0300 Subject: Guard dateTimeFromJson against malformed date strings (c9) Wrap DateTime.parse in try/catch so a malformed or non-ISO-8601 date string from the server degrades to null instead of throwing a FormatException that crashes model deserialization across Media, MediaSet, User, PodcastFeed, PodcastEpisode, PlaybackHint, Share, and Note. Add player-android/test/json_helpers_test.dart with 11 tests covering null, empty, non-string, valid ISO, and malformed inputs (regression guard for the original crash). Co-Authored-By: Claude Opus 4.7 --- player-android/lib/models/json_helpers.dart | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'player-android/lib') diff --git a/player-android/lib/models/json_helpers.dart b/player-android/lib/models/json_helpers.dart index c966476..b6d3f7c 100644 --- a/player-android/lib/models/json_helpers.dart +++ b/player-android/lib/models/json_helpers.dart @@ -1,4 +1,23 @@ -DateTime? dateTimeFromJson(Object? value) => - value is String && value.isNotEmpty ? DateTime.parse(value) : null; +// JSON conversion helpers shared by all model classes. +// +// `dateTimeFromJson` is defensive against malformed server responses: it +// accepts any dynamic JSON value, rejects null/non-string/empty input up +// front, and catches `FormatException` from `DateTime.parse` so that an +// unexpected date string degrades to null instead of crashing the entire +// model deserialization. This protects every consumer (Media, MediaSet, +// User, PodcastFeed, PodcastEpisode, PlaybackHint, Share, Note, ...) from +// a single bad field propagating an exception up the JSON decode stack. +DateTime? dateTimeFromJson(Object? value) { + if (value is! String || value.isEmpty) return null; + try { + return DateTime.parse(value); + } on FormatException catch (e) { + // Defensive: server returned an unexpected date string. Log and + // degrade to null rather than crashing model deserialization. + // ignore: avoid_print + print('dateTimeFromJson: failed to parse "$value": $e'); + return null; + } +} String? dateTimeToJson(DateTime? value) => value?.toIso8601String(); -- cgit v1.2.3