Better exception handling
This commit is contained in:
parent
7e1723786f
commit
89c073fd51
|
@ -3,25 +3,16 @@ import 'package:http/http.dart';
|
|||
import 'youtube_explode_exception.dart';
|
||||
|
||||
/// Exception thrown when a fatal failure occurs.
|
||||
class FatalFailureException implements YoutubeExplodeException {
|
||||
/// Description message
|
||||
@override
|
||||
final String message;
|
||||
|
||||
class FatalFailureException extends YoutubeExplodeException {
|
||||
/// Initializes an instance of [FatalFailureException]
|
||||
FatalFailureException(this.message);
|
||||
FatalFailureException(String message) : super(message);
|
||||
|
||||
/// Initializes an instance of [FatalFailureException] with a [Response]
|
||||
FatalFailureException.httpRequest(BaseResponse response)
|
||||
: message = '''
|
||||
FatalFailureException.httpRequest(BaseResponse response) : super('''
|
||||
Failed to perform an HTTP request to YouTube due to a fatal failure.
|
||||
In most cases, this error indicates that YouTube most likely changed something, which broke the library.
|
||||
If this issue persists, please report it on the project's GitHub page.
|
||||
Request: ${response.request}
|
||||
Response: (${response.statusCode})
|
||||
''';
|
||||
|
||||
@override
|
||||
String toString() =>
|
||||
'$runtimeType: $message'; // ignore: no_runtimetype_tostring
|
||||
''');
|
||||
}
|
||||
|
|
|
@ -3,26 +3,17 @@ import 'package:http/http.dart';
|
|||
import 'youtube_explode_exception.dart';
|
||||
|
||||
/// Exception thrown when a fatal failure occurs.
|
||||
class RequestLimitExceededException implements YoutubeExplodeException {
|
||||
/// Description message
|
||||
@override
|
||||
final String message;
|
||||
|
||||
class RequestLimitExceededException extends YoutubeExplodeException {
|
||||
/// Initializes an instance of [RequestLimitExceededException]
|
||||
RequestLimitExceededException(this.message);
|
||||
RequestLimitExceededException(String message) : super(message);
|
||||
|
||||
/// Initializes an instance of [RequestLimitExceeded] with a [Response]
|
||||
RequestLimitExceededException.httpRequest(BaseResponse response)
|
||||
: message = '''
|
||||
RequestLimitExceededException.httpRequest(BaseResponse response) : super('''
|
||||
Failed to perform an HTTP request to YouTube because of rate limiting.
|
||||
This error indicates that YouTube thinks there were too many requests made from this IP and considers it suspicious.
|
||||
To resolve this error, please wait some time and try again -or- try injecting an HttpClient that has cookies for an authenticated user.
|
||||
Unfortunately, there's nothing the library can do to work around this error.
|
||||
Request: ${response.request}
|
||||
Response: $response
|
||||
''';
|
||||
|
||||
@override
|
||||
String toString() =>
|
||||
'$runtimeType: $message'; // ignore: no_runtimetype_tostring
|
||||
''');
|
||||
}
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
import '../../youtube_explode_dart.dart';
|
||||
|
||||
/// Exception thrown when the Item Section is missing from a search request.
|
||||
class SearchItemSectionException implements YoutubeExplodeException {
|
||||
@override
|
||||
// TODO: implement message
|
||||
String get message => 'Failed to find the item section.';
|
||||
class SearchItemSectionException extends YoutubeExplodeException {
|
||||
SearchItemSectionException() : super('Failed to find the item section.');
|
||||
}
|
||||
|
|
|
@ -3,25 +3,17 @@ import 'package:http/http.dart';
|
|||
import 'youtube_explode_exception.dart';
|
||||
|
||||
/// Exception thrown when a fatal failure occurs.
|
||||
class TransientFailureException implements YoutubeExplodeException {
|
||||
@override
|
||||
final String message;
|
||||
|
||||
class TransientFailureException extends YoutubeExplodeException {
|
||||
/// Initializes an instance of [TransientFailureException]
|
||||
TransientFailureException(this.message);
|
||||
TransientFailureException(String message) : super(message);
|
||||
|
||||
/// Initializes an instance of [TransientFailureException] with a [Response]
|
||||
TransientFailureException.httpRequest(BaseResponse response)
|
||||
: message = '''
|
||||
TransientFailureException.httpRequest(BaseResponse response) : super('''
|
||||
Failed to perform an HTTP request to YouTube due to a transient failure.
|
||||
In most cases, this error indicates that the problem is on YouTube's side and this is not a bug in the library.
|
||||
To resolve this error, please wait some time and try again.
|
||||
If this issue persists, please report it on the project's GitHub page.
|
||||
Request: ${response.request}
|
||||
Response: $response
|
||||
''';
|
||||
|
||||
@override
|
||||
String toString() =>
|
||||
'$runtimeType: $message'; // ignore: no_runtimetype_tostring
|
||||
''');
|
||||
}
|
||||
|
|
|
@ -2,22 +2,13 @@ import '../videos/video_id.dart';
|
|||
import 'video_unplayable_exception.dart';
|
||||
|
||||
/// Exception thrown when the requested video requires purchase.
|
||||
class VideoRequiresPurchaseException implements VideoUnplayableException {
|
||||
/// Description message
|
||||
@override
|
||||
final String message;
|
||||
|
||||
class VideoRequiresPurchaseException extends VideoUnplayableException {
|
||||
/// VideoId instance
|
||||
final VideoId previewVideoId;
|
||||
|
||||
/// Initializes an instance of [VideoRequiresPurchaseException].
|
||||
VideoRequiresPurchaseException.preview(VideoId videoId, this.previewVideoId)
|
||||
: message =
|
||||
'Video `$videoId` is unplayable because it requires purchase.\n'
|
||||
'Streams are not available for this video.\n'
|
||||
'There is a preview video available: `$previewVideoId`.';
|
||||
|
||||
@override
|
||||
String toString() =>
|
||||
'$runtimeType: $message'; // ignore: no_runtimetype_tostring
|
||||
: super('Video `$videoId` is unplayable because it requires purchase.\n'
|
||||
'Streams are not available for this video.\n'
|
||||
'There is a preview video available: `$previewVideoId`.');
|
||||
}
|
||||
|
|
|
@ -4,24 +4,16 @@ import 'exceptions.dart';
|
|||
/// Thrown when a video is not available and cannot be processed.
|
||||
/// This can happen because the video does not exist, is deleted,
|
||||
/// is private, or due to other reasons.
|
||||
class VideoUnavailableException implements VideoUnplayableException {
|
||||
/// Description message
|
||||
@override
|
||||
final String message;
|
||||
|
||||
class VideoUnavailableException extends VideoUnplayableException {
|
||||
/// Initializes an instance of [VideoUnavailableException]
|
||||
VideoUnavailableException(this.message);
|
||||
VideoUnavailableException(String message) : super(message);
|
||||
|
||||
/// Initializes an instance of [VideoUnplayableException] with a [VideoId]
|
||||
VideoUnavailableException.unavailable(VideoId videoId)
|
||||
: message = 'Video \'$videoId\' is unavailable\n'
|
||||
: super('Video \'$videoId\' is unavailable\n'
|
||||
'In most cases, this error indicates that the video doesn\'t exist, ' // ignore: lines_longer_than_80_chars
|
||||
'is private, or has been taken down.\n'
|
||||
'If you can however open this video in your browser in incognito mode, ' // ignore: lines_longer_than_80_chars
|
||||
'it most likely means that YouTube changed something, which broke this library.\n' // ignore: lines_longer_than_80_chars
|
||||
'Please report this issue on GitHub in that case.';
|
||||
|
||||
@override
|
||||
String toString() =>
|
||||
'$runtimeType: $message'; // ignore: no_runtimetype_tostring
|
||||
'Please report this issue on GitHub in that case.');
|
||||
}
|
||||
|
|
|
@ -2,35 +2,26 @@ import '../videos/video_id.dart';
|
|||
import 'youtube_explode_exception.dart';
|
||||
|
||||
/// Exception thrown when the requested video is unplayable.
|
||||
class VideoUnplayableException implements YoutubeExplodeException {
|
||||
/// Description message
|
||||
@override
|
||||
final String message;
|
||||
|
||||
class VideoUnplayableException extends YoutubeExplodeException {
|
||||
/// Initializes an instance of [VideoUnplayableException]
|
||||
VideoUnplayableException(this.message);
|
||||
VideoUnplayableException(String message) : super(message);
|
||||
|
||||
/// Initializes an instance of [VideoUnplayableException] with a [VideoId]
|
||||
VideoUnplayableException.unplayable(VideoId videoId, {String reason = ''})
|
||||
: message = 'Video \'$videoId\' is unplayable.\n'
|
||||
: super('Video \'$videoId\' is unplayable.\n'
|
||||
'Streams are not available for this video.\n'
|
||||
'In most cases, this error indicates that there are \n'
|
||||
'some restrictions in place that prevent watching this video.\n'
|
||||
'Reason: $reason';
|
||||
'Reason: $reason');
|
||||
|
||||
/// Initializes an instance of [VideoUnplayableException] with a [VideoId]
|
||||
VideoUnplayableException.liveStream(VideoId videoId)
|
||||
: message = 'Video \'$videoId\' is an ongoing live stream.\n'
|
||||
: super('Video \'$videoId\' is an ongoing live stream.\n'
|
||||
'Streams are not available for this video.\n'
|
||||
'Please wait until the live stream finishes and try again.';
|
||||
'Please wait until the live stream finishes and try again.');
|
||||
|
||||
/// Initializes an instance of [VideoUnplayableException] with a [VideoId]
|
||||
VideoUnplayableException.notLiveStream(VideoId videoId)
|
||||
: message = 'Video \'$videoId\' is not an ongoing live stream.\n'
|
||||
'Live stream manifest is not available for this video';
|
||||
|
||||
@override
|
||||
// ignore:
|
||||
String toString() =>
|
||||
'$runtimeType: $message'; // ignore: no_runtimetype_tostring
|
||||
: super('Video \'$videoId\' is not an ongoing live stream.\n'
|
||||
'Live stream manifest is not available for this video');
|
||||
}
|
||||
|
|
|
@ -3,6 +3,28 @@ abstract class YoutubeExplodeException implements Exception {
|
|||
/// Generic message.
|
||||
final String message;
|
||||
|
||||
/// Addition exceptions thrown.
|
||||
final List<YoutubeExplodeException> _others = [];
|
||||
|
||||
/// Add another exception to the stack.
|
||||
void combine(YoutubeExplodeException e) => _others.add(e);
|
||||
|
||||
///
|
||||
YoutubeExplodeException(this.message);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
if (_others.isEmpty) {
|
||||
return '$runtimeType: $message';
|
||||
}
|
||||
final buffer = StringBuffer('$runtimeType: $message\n\n');
|
||||
buffer.writeln('Additionally these exceptions where thrown in the stack');
|
||||
for (final e in _others) {
|
||||
buffer.writeln('---');
|
||||
buffer.writeln(e.toString());
|
||||
buffer.writeln('---');
|
||||
}
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -226,9 +226,13 @@ class StreamsClient {
|
|||
try {
|
||||
var context = await _getStreamContextFromVideoInfo(videoId);
|
||||
return _getManifest(context);
|
||||
} on YoutubeExplodeException {
|
||||
var context = await _getStreamContextFromWatchPage(videoId);
|
||||
return _getManifest(context);
|
||||
} on YoutubeExplodeException catch (e) {
|
||||
try {
|
||||
var context = await _getStreamContextFromWatchPage(videoId);
|
||||
return _getManifest(context);
|
||||
} on YoutubeExplodeException catch (e1) {
|
||||
throw e..combine(e1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue