Skip to content

Commit

Permalink
Merge pull request #591 from hpi-studyu/issue/564-future-proof-deseri…
Browse files Browse the repository at this point in the history
…alization-with-exceptions-v2-hig

refactor: improve return type of publishedPublicStudies()
  • Loading branch information
hig-dev committed Mar 6, 2024
2 parents 5ef1bc4 + fedec44 commit 4639fd7
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 25 deletions.
15 changes: 8 additions & 7 deletions app/lib/screens/study/onboarding/study_selection.dart
Original file line number Diff line number Diff line change
Expand Up @@ -91,23 +91,24 @@ class StudySelectionScreen extends StatelessWidget {
),
),
Expanded(
child: RetryFutureBuilder<ExtractingFailedException<Study>>(
child: RetryFutureBuilder<ExtractionResult<Study>>(
tryFunction: () async => Study.publishedPublicStudies(),
successBuilder: (BuildContext context, ExtractingFailedException<Study>? studies) {
if (studies!.notExtracted.isNotEmpty) {
debugPrint('${studies.notExtracted.length} studies could not be extracted.');
successBuilder: (BuildContext context, ExtractionResult<Study>? extractionResult) {
final studies = extractionResult!.extracted;
if (extractionResult is ExtractionFailedException<Study>) {
debugPrint('${extractionResult.notExtracted.length} studies could not be extracted.');
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(AppLocalizations.of(context)!.study_selection_hidden_studies),
),
);
}
return ListView.builder(
itemCount: studies.extracted.length,
itemCount: studies.length,
itemBuilder: (context, index) {
final study = studies.extracted[index];
final study = studies[index];
return Hero(
tag: 'study_tile_${studies.extracted[index].id}',
tag: 'study_tile_${studies[index].id}',
child: Material(
child: StudyTile.fromStudy(
study: study,
Expand Down
17 changes: 7 additions & 10 deletions core/lib/src/models/tables/study.dart
Original file line number Diff line number Diff line change
Expand Up @@ -167,22 +167,19 @@ class Study extends SupabaseObjectFunctions<Study> implements Comparable<Study>
);

// ['id', 'title', 'description', 'published', 'icon_name', 'results', 'schedule']
static Future<ExtractingFailedException<Study>> publishedPublicStudies() async {
List<Study> extractedStudies;
List<JsonWithError> notExtracted = [];
static Future<ExtractionResult<Study>> publishedPublicStudies() async {
ExtractionResult<Study> result;
try {
final response = await env.client.from(tableName).select().eq('participation', 'open');
extractedStudies = SupabaseQuery.extractSupabaseList<Study>(List<Map<String, dynamic>>.from(response));
} on ExtractingFailedException<Study> catch (error) {
// If some records could not be extracted, catch the exception and
// return the extracted records and the faulty records
extractedStudies = error.extracted;
notExtracted = error.notExtracted;
final extracted = SupabaseQuery.extractSupabaseList<Study>(List<Map<String, dynamic>>.from(response));
result = ExtractionSuccess<Study>(extracted);
} on ExtractionFailedException<Study> catch (error) {
result = error;
} catch (error, stacktrace) {
SupabaseQuery.catchSupabaseException(error, stacktrace);
rethrow;
}
return ExtractingFailedException<Study>(extractedStudies, notExtracted);
return result;
}

bool isOwner(User? user) => user != null && userId == user.id;
Expand Down
21 changes: 13 additions & 8 deletions core/lib/src/util/supabase_object.dart
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class SupabaseQuery {
}

/// Extracts a list of SupabaseObjects from a response.
/// If some records could not be extracted, [ExtractedSupabaseListResult] is
/// If some records could not be extracted, [ExtractionFailedException] is
/// thrown containing the extracted records and the faulty records.
static List<T> extractSupabaseList<T extends SupabaseObject>(
List<Map<String, dynamic>> response,
Expand All @@ -99,7 +99,7 @@ class SupabaseQuery {
if (notExtracted.isNotEmpty) {
// If some records could not be extracted, we throw an exception
// with the extracted records and the faulty records
throw ExtractingFailedException(extracted, notExtracted);
throw ExtractionFailedException(extracted, notExtracted);
}
return extracted;
}
Expand Down Expand Up @@ -138,15 +138,20 @@ extension PrimaryKeyFilterBuilder on PostgrestFilterBuilder {
}
}

abstract class IExtractingFailedException<T> implements Exception {
const IExtractingFailedException(this.extracted, this.notExtracted);

sealed class ExtractionResult<T> {
final List<T> extracted;
final List<JsonWithError> notExtracted;

ExtractionResult(this.extracted);
}

class ExtractingFailedException<T> extends IExtractingFailedException<T> {
ExtractingFailedException(super.extracted, super.notExtracted);
class ExtractionSuccess<T> extends ExtractionResult<T> {
ExtractionSuccess(super.extracted);
}

class ExtractionFailedException<T> extends ExtractionResult<T> implements Exception {
final List<JsonWithError> notExtracted;

ExtractionFailedException(super.extracted, this.notExtracted);
}

class JsonWithError {
Expand Down

0 comments on commit 4639fd7

Please sign in to comment.