Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,4 @@ jobs:
flutter test integration_test/rockets_screen_integration_test.dart --flavor dev
flutter test integration_test/rocket_screen_test.dart --flavor dev
flutter test integration_test/rockets_integration_live_test.dart --flavor dev
flutter test integration_test/roadster_detail_integration_test.dart --flavor dev
26 changes: 26 additions & 0 deletions lib/data/network/data_source/roadster_network_data_source.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import 'package:dio/dio.dart';
import 'package:flutter_bloc_app_template/data/network/api_result.dart';
import 'package:flutter_bloc_app_template/data/network/model/roadster/network_roadster_model.dart';
import 'package:flutter_bloc_app_template/data/network/service/roadster/roadster_service.dart';
Comment on lines +2 to +4
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Tighten error handling and remove unnecessary Future.value

Catch DioException explicitly and return error without wrapping in Future.value.

+import 'package:dio/dio.dart';
 import 'package:flutter_bloc_app_template/data/network/api_result.dart';
 import 'package:flutter_bloc_app_template/data/network/model/roadster/network_roadster_model.dart';
 import 'package:flutter_bloc_app_template/data/network/service/roadster/roadster_service.dart';

   @override
   Future<ApiResult<NetworkRoadsterModel>> getRoadster() async {
     try {
       final result = await _service.fetchRoadster();
       return ApiResult.success(result);
-    } catch (e) {
-      return Future.value(ApiResult.error(e.toString()));
+    } on DioException catch (e) {
+      return ApiResult.error(e.message ?? e.toString());
+    } catch (e) {
+      return ApiResult.error(e.toString());
     }
   }

Also applies to: 14-21

🤖 Prompt for AI Agents
In lib/data/network/data_source/roadster_network_data_source.dart around lines
1-3 (and similarly lines 14-21), the current error handling wraps errors in
Future.value and doesn't explicitly catch DioException; change the try/catch so
you catch DioException on its own (e.g. on DioException catch (e)) and return
the ApiResult error directly (no Future.value wrapper), and add a generic catch
(e, s) to return ApiResult.error for other exceptions; ensure the method still
returns the correct ApiResult type without unnecessary Future.value calls.


abstract class RoadsterDataSource {
Future<ApiResult<NetworkRoadsterModel>> getRoadster();
}

class RoadsterNetworkDataSource implements RoadsterDataSource {
RoadsterNetworkDataSource(this._service);

final RoadsterService _service;

@override
Future<ApiResult<NetworkRoadsterModel>> getRoadster() async {
try {
final result = await _service.fetchRoadster();
return ApiResult.success(result);
} on DioException catch (e) {
return ApiResult.error(e.message ?? e.toString());
} catch (e) {
return Future.value(ApiResult.error(e.toString()));
}
}
}
12 changes: 0 additions & 12 deletions lib/data/network/model/core/network_core_model.freezed.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 42 additions & 0 deletions lib/data/network/model/roadster/network_roadster_model.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import 'package:freezed_annotation/freezed_annotation.dart';

part 'network_roadster_model.freezed.dart';
part 'network_roadster_model.g.dart';

@freezed
abstract class NetworkRoadsterModel with _$NetworkRoadsterModel {
const factory NetworkRoadsterModel({
String? name,
@JsonKey(name: 'launch_date_utc') String? launchDateUtc,
@JsonKey(name: 'launch_date_unix') int? launchDateUnix,
@JsonKey(name: 'launch_mass_kg') int? launchMassKg,
@JsonKey(name: 'launch_mass_lbs') int? launchMassLbs,
@JsonKey(name: 'norad_id') int? noradId,
@JsonKey(name: 'epoch_jd') double? epochJd,
@JsonKey(name: 'orbit_type') String? orbitType,
@JsonKey(name: 'apoapsis_au') double? apoapsisAu,
@JsonKey(name: 'periapsis_au') double? periapsisAu,
@JsonKey(name: 'semi_major_axis_au') double? semiMajorAxisAu,
double? eccentricity,
double? inclination,
double? longitude,
@JsonKey(name: 'periapsis_arg') double? periapsisArg,
@JsonKey(name: 'period_days') double? periodDays,
@JsonKey(name: 'speed_kph') double? speedKph,
@JsonKey(name: 'speed_mph') double? speedMph,
@JsonKey(name: 'earth_distance_km') double? earthDistanceKm,
@JsonKey(name: 'earth_distance_mi') double? earthDistanceMi,
@JsonKey(name: 'mars_distance_km') double? marsDistanceKm,
@JsonKey(name: 'mars_distance_mi') double? marsDistanceMi,
@JsonKey(name: 'flickr_images') List<String>? flickrImages,
String? wikipedia,
String? video,
String? details,
String? id,
}) = _NetworkRoadsterModel;

const NetworkRoadsterModel._();

factory NetworkRoadsterModel.fromJson(Map<String, dynamic> json) =>
_$NetworkRoadsterModelFromJson(json);
}
Loading
Loading