Skip to content

Commit

Permalink
Publication date is now optional.
Browse files Browse the repository at this point in the history
  • Loading branch information
amugofjava committed Jul 7, 2023
1 parent 509d697 commit 1fb9d0c
Show file tree
Hide file tree
Showing 9 changed files with 109 additions and 63 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 0.6.1

- Publication date is now optional.
- Additional exceptions for certificate & general errors.
- Move to Dio 5.x.

## 0.6.0

- Breaking change: Requires Dart 3.0.
Expand Down
14 changes: 14 additions & 0 deletions lib/src/exceptions/search_exceptions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,17 @@ class PodcastFailedException implements Exception {

PodcastFailedException(this.message);
}

/// Thrown if we get a certificate error.
class PodcastCertificateException implements Exception {
final String message;

PodcastCertificateException(this.message);
}

/// Thrown if we get an unknown error.
class PodcastUnknownException implements Exception {
final String message;

PodcastUnknownException(this.message);
}
104 changes: 60 additions & 44 deletions lib/src/model/podcast.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class Podcast {
/// be used in HTTP/HTTPS communications with the feed source.
static Future<Podcast> loadFeed({
required String url,
int timeout = 20000,
final timeout = const Duration(seconds: 20),
String userAgent = '',
}) async {
final client = Dio(
Expand All @@ -90,17 +90,21 @@ class Podcast {

// Parse the episodes
return _loadFeed(rssFeed, url);
} on DioError catch (e) {
} on DioException catch (e) {
switch (e.type) {
case DioErrorType.connectTimeout:
case DioErrorType.sendTimeout:
case DioErrorType.receiveTimeout:
case DioErrorType.other:
throw PodcastTimeoutException(e.message);
case DioErrorType.response:
throw PodcastFailedException(e.message);
case DioErrorType.cancel:
throw PodcastCancelledException(e.message);
case DioExceptionType.connectionTimeout:
case DioExceptionType.sendTimeout:
case DioExceptionType.receiveTimeout:
throw PodcastTimeoutException(e.message ?? '');
case DioExceptionType.connectionError:
case DioExceptionType.badResponse:
throw PodcastFailedException(e.message ?? '');
case DioExceptionType.badCertificate:
throw PodcastCertificateException(e.message ?? '');
case DioExceptionType.cancel:
throw PodcastCancelledException(e.message ?? '');
case DioExceptionType.unknown:
throw PodcastUnknownException(e.message ?? '');
}
}
}
Expand Down Expand Up @@ -204,7 +208,7 @@ class Podcast {
static Future<Episode> loadEpisodeChapters({
required Episode episode,
bool forceReload = false,
int timeout = 20000,
final timeout = const Duration(seconds: 20),
}) async {
final client = Dio(
BaseOptions(
Expand All @@ -223,17 +227,21 @@ class Podcast {
response.data is Map<String, dynamic>) {
_loadChapters(response, episode.chapters!);
}
} on DioError catch (e) {
} on DioException catch (e) {
switch (e.type) {
case DioErrorType.connectTimeout:
case DioErrorType.sendTimeout:
case DioErrorType.receiveTimeout:
case DioErrorType.other:
throw PodcastTimeoutException(e.message);
case DioErrorType.response:
throw PodcastFailedException(e.message);
case DioErrorType.cancel:
throw PodcastCancelledException(e.message);
case DioExceptionType.connectionTimeout:
case DioExceptionType.sendTimeout:
case DioExceptionType.receiveTimeout:
throw PodcastTimeoutException(e.message ?? '');
case DioExceptionType.connectionError:
case DioExceptionType.badResponse:
throw PodcastFailedException(e.message ?? '');
case DioExceptionType.badCertificate:
throw PodcastCertificateException(e.message ?? '');
case DioExceptionType.cancel:
throw PodcastCancelledException(e.message ?? '');
case DioExceptionType.unknown:
throw PodcastUnknownException(e.message ?? '');
}
}
}
Expand All @@ -246,7 +254,7 @@ class Podcast {
/// [JsonParser] or [SrtParser] is used.
static Future<Transcript> loadTranscriptByUrl({
required TranscriptUrl transcriptUrl,
int timeout = 20000,
final timeout = const Duration(seconds: 20),
}) async {
final client = Dio(
BaseOptions(
Expand Down Expand Up @@ -275,17 +283,21 @@ class Podcast {
} else {
throw Exception('Sorry, not got around to supporting that format yet');
}
} on DioError catch (e) {
} on DioException catch (e) {
switch (e.type) {
case DioErrorType.connectTimeout:
case DioErrorType.sendTimeout:
case DioErrorType.receiveTimeout:
case DioErrorType.other:
throw PodcastTimeoutException(e.message);
case DioErrorType.response:
throw PodcastFailedException(e.message);
case DioErrorType.cancel:
throw PodcastCancelledException(e.message);
case DioExceptionType.connectionTimeout:
case DioExceptionType.sendTimeout:
case DioExceptionType.receiveTimeout:
throw PodcastTimeoutException(e.message ?? '');
case DioExceptionType.connectionError:
case DioExceptionType.badResponse:
throw PodcastFailedException(e.message ?? '');
case DioExceptionType.badCertificate:
throw PodcastCertificateException(e.message ?? '');
case DioExceptionType.cancel:
throw PodcastCancelledException(e.message ?? '');
case DioExceptionType.unknown:
throw PodcastUnknownException(e.message ?? '');
}
}

Expand All @@ -297,7 +309,7 @@ class Podcast {
/// and loads the chapters, return a populated Chapters object.
static Future<Chapters> loadChaptersByUrl({
required String url,
int timeout = 20000,
final timeout = const Duration(seconds: 20),
}) async {
final client = Dio(
BaseOptions(
Expand All @@ -316,17 +328,21 @@ class Podcast {
} else {
throw PodcastFailedException('Failed to download chapters file');
}
} on DioError catch (e) {
} on DioException catch (e) {
switch (e.type) {
case DioErrorType.connectTimeout:
case DioErrorType.sendTimeout:
case DioErrorType.receiveTimeout:
case DioErrorType.other:
throw PodcastTimeoutException(e.message);
case DioErrorType.response:
throw PodcastFailedException(e.message);
case DioErrorType.cancel:
throw PodcastCancelledException(e.message);
case DioExceptionType.connectionTimeout:
case DioExceptionType.sendTimeout:
case DioExceptionType.receiveTimeout:
throw PodcastTimeoutException(e.message ?? '');
case DioExceptionType.connectionError:
case DioExceptionType.badResponse:
throw PodcastFailedException(e.message ?? '');
case DioExceptionType.badCertificate:
throw PodcastCertificateException(e.message ?? '');
case DioExceptionType.cancel:
throw PodcastCancelledException(e.message ?? '');
case DioExceptionType.unknown:
throw PodcastUnknownException(e.message ?? '');
}
}

Expand Down
2 changes: 2 additions & 0 deletions lib/src/model/search_result.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ enum ErrorType {
cancelled,
failed,
connection,
certificate,
timeout,
unknown,
}

enum ResultType {
Expand Down
22 changes: 15 additions & 7 deletions lib/src/search/base_search.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,23 +36,31 @@ abstract class BaseSearch {
/// determine the error and set two variables which can then be included
/// in the results. The client can then use these variables to determine
/// if there was an issue or not.
void setLastError(DioError e) {
void setLastError(DioException e) {
switch (e.type) {
case DioErrorType.connectTimeout:
case DioErrorType.sendTimeout:
case DioErrorType.receiveTimeout:
case DioErrorType.other:
case DioExceptionType.connectionTimeout:
case DioExceptionType.sendTimeout:
case DioExceptionType.receiveTimeout:
lastErrorType = ErrorType.connection;
lastError = 'Connection timeout';
break;
case DioErrorType.response:
case DioExceptionType.badCertificate:
lastErrorType = ErrorType.certificate;
lastError = 'Certificate error';
break;
case DioExceptionType.connectionError:
case DioExceptionType.badResponse:
lastErrorType = ErrorType.failed;
lastError = 'Server returned response error ${e.response?.statusCode}';
break;
case DioErrorType.cancel:
case DioExceptionType.cancel:
lastErrorType = ErrorType.cancelled;
lastError = 'Request was cancelled';
break;
case DioExceptionType.unknown:
lastErrorType = ErrorType.unknown;
lastError = 'Unknown error';
break;
}
}
}
10 changes: 5 additions & 5 deletions lib/src/search/itunes_search.dart
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ final class ITunesSearch extends BaseSearch {
}) : _client = Dio(
BaseOptions(
responseType: ResponseType.plain,
connectTimeout: timeout,
receiveTimeout: timeout,
connectTimeout: Duration(milliseconds: timeout),
receiveTimeout: Duration(milliseconds: timeout),
headers: {
'User-Agent': userAgent == null || userAgent.isEmpty
? podcastSearchAgent
Expand Down Expand Up @@ -112,7 +112,7 @@ final class ITunesSearch extends BaseSearch {
final results = json.decode(response.data);

return SearchResult.fromJson(json: results);
} on DioError catch (e) {
} on DioException catch (e) {
setLastError(e);
}

Expand Down Expand Up @@ -149,7 +149,7 @@ final class ITunesSearch extends BaseSearch {
final results = json.decode(response.data);

return await _chartsToResults(results);
} on DioError catch (e) {
} on DioException catch (e) {
setLastError(e);
}

Expand Down Expand Up @@ -182,7 +182,7 @@ final class ITunesSearch extends BaseSearch {
}

return SearchResult(resultCount: items.length, items: items);
} on DioError catch (e) {
} on DioException catch (e) {
setLastError(e);
}

Expand Down
8 changes: 4 additions & 4 deletions lib/src/search/podcast_index_search.dart
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,8 @@ final class PodcastIndexSearch extends BaseSearch {

_client = Dio(
BaseOptions(
connectTimeout: timeout,
receiveTimeout: timeout,
connectTimeout: Duration(milliseconds: timeout),
receiveTimeout: Duration(milliseconds: timeout),
responseType: ResponseType.json,
headers: {
'X-Auth-Date': newUnixTime,
Expand Down Expand Up @@ -220,7 +220,7 @@ final class PodcastIndexSearch extends BaseSearch {

return SearchResult.fromJson(
json: response.data, type: ResultType.podcastIndex);
} on DioError catch (e) {
} on DioException catch (e) {
setLastError(e);
}

Expand Down Expand Up @@ -254,7 +254,7 @@ final class PodcastIndexSearch extends BaseSearch {

return SearchResult.fromJson(
json: response.data, type: ResultType.podcastIndex);
} on DioError catch (e) {
} on DioException catch (e) {
setLastError(e);
}

Expand Down
4 changes: 2 additions & 2 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ dependencies:
archive: ^3.1.2
convert: ^3.0.1
crypto: ^3.0.1
dio: ^4.0.0
dio: ^5.2.1+1
rss_dart: ^1.0.3
meta: ^1.8.0

dev_dependencies:
flutter_lints: ^2.0.1
test: ^1.9.4
test: ^1.24.4
2 changes: 1 addition & 1 deletion test/podcast_load_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ void main() {

test('Load invalid podcast - timeout', () async {
await expectLater(() => Podcast.loadFeed(url: 'https://pc.files.bbci.co.uk/p06tqsg3.rss'),
throwsA(const TypeMatcher<PodcastTimeoutException>()));
throwsA(const TypeMatcher<PodcastUnknownException>()));
});
});

Expand Down

0 comments on commit 1fb9d0c

Please sign in to comment.