just_audio
just_audio copied to clipboard
An Unhandled Exception is thrown when loading LockCachingAudioSource fails.
Which API doesn't behave as documented, and how does it misbehave? Set audio source to LockCachingAudioSource type, preload to false, get Unhandled Exception after calling player.load method.
Minimal reproduction project The example
try {
final source = LockCachingAudioSource(Uri.parse(
"https://no-exist-url.test-host/test.mp3"));
await _player.setAudioSource(source, preload: false);
// Calling the load method at other times
await _player.load();
} catch (e) {
print("Error loading audio source: $e");
}
To Reproduce (i.e. user steps, not code) Steps to reproduce the behavior:
- Set audio source to LockCachingAudioSource type, preload to false.
- Call player.load method.
Error messages
[VERBOSE-2:dart_vm_initializer.cc(41)] Unhandled Exception: SocketException: Failed host lookup: 'no-exist-url.test-host' (OS Error: nodename nor servname provided, or not known, errno = 8)
#0 _NativeSocket.startConnect (dart:io-patch/socket_patch.dart:682:35)
#1 _RawSocket.startConnect (dart:io-patch/socket_patch.dart:1827:26)
#2 RawSocket.startConnect (dart:io-patch/socket_patch.dart:27:23)
#3 RawSecureSocket.startConnect (dart:io/secure_socket.dart:299:22)
#4 SecureSocket.startConnect (dart:io/secure_socket.dart:77:28)
#5 _ConnectionTarget.connect (dart:_http/http_impl.dart:2449:26)
#6 _HttpClient._getConnection.connect (dart:_http/http_impl.dart:2867:12)
#7 _HttpClient._getConnection (dart:_http/http_impl.dart:2872:12)
#8 _HttpClient._openUrl (dart:_http/http_impl.dart:2727:12)
#9 _HttpClient.getUrl (dart:_http/http_impl.dart:2596:48)
#10 _getUrl (package:just_audio/just_audio.dart:3936:32)
#11 LockCachingAudioSource._fetch (package:just_a<…>
Expected behavior An Unhandled Exception is thrown.
Screenshots N/A
Desktop (please complete the following information): Not running on Desktop / Web
Smartphone (please complete the following information):
- Device: iPhone8
- OS: iOS16.1
Flutter SDK version
Flutter 3.3.3
Additional context The code that threw the exception: In LockCachingAudioSource.request(), Future error is thrown when fetch fails, but cannot be handled.
// Line: 3120
_response ??=
_fetch().catchError((dynamic error, StackTrace? stackTrace) async {
_response = null;
for (final req in _requests) {
req.fail(error, stackTrace);
}
// Return a Future Error, which cannot be handled by outer.
return Future<HttpClientResponse>.error(error as Object, stackTrace);
});
Bug Fix Suggestion: I think it's unnecessary to cache the fetch Future object, but rather use an isFetching variable to preserve the state. Since there isn't currently any retry logic, the fetch result is actually ignore. Even if retry logic is added later, call the fetch method directly and does not require the last failed Future object.
bool _isFetching = false;
Future<void> _fetchIgnoreResult() async {
try {
await _fetch();
} catch (error, stackTrace) {
// Cancel any pending request
for (final req in _requests) {
req.fail(error, stackTrace);
}
}
_isFetching = false;
}
if (!_isFetching) {
_isFetching = true;
_fetchIgnoreResult();
}