-
-
Notifications
You must be signed in to change notification settings - Fork 686
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix error handling on play without load #554
base: minor
Are you sure you want to change the base?
Fix error handling on play without load #554
Conversation
just_audio/lib/just_audio.dart
Outdated
_sendPlayRequest(await _platform, playCompleter); | ||
_sendPlayRequest(await _platform, playCompleter) | ||
.catchError((dynamic e) { | ||
_playingSubject.add(false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if I would want to automatically set playing
to false here, that logic should be left to the app to decide once they catch the error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought the same thing. But is it possible that send play request occurs error and still in playing?
I think it's more likely as same as revert state if failed to activate the audio session.
https://github.com/ryanheise/just_audio/blob/master/just_audio/lib/just_audio.dart#L867-L868
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only methods that should set playing
are play
, pause
and stop
. Now if this code is happening as part of play
, then in principle it is fine, but this line is still in the wrong place. The error needs to be propagated back to the play
method body where it can be caught and THEN playing
set to false
.
I'm still a bit conflicted about this, though. Reverting the state is not as good as never setting the state in the first place. What I did to handle the audio session error is a bit of a kludge to allow the UI to get immediate state feedback synchronously before trying to activate the audio session asynchronously. The other half of my conflicted brain is thinking that I should just remove the reversion code and leave it dangling in the playing state there, too, but report the exception to the app so that it can decide what to do in that situation. The reason being is that the state model was designed so that the playing
state is only ever set in direct response to a request by the app. The reversion was not actually the original request. Although perhaps play
could have a parameter to configure whether this reversion happens or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got it! Yes, probably the playing state should only be changed by method call, however error recovery and auto state changing is also useful.
Anyway, this PR's main purpose is to fix error dropping on play without load. So how about this?
- revert playing state changing for this PR.
- add new enhancement issue about auto playing state recovery option as a reminder.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've done all two things above.
just_audio/lib/just_audio.dart
Outdated
} else { | ||
// If the native platform wasn't already active, activating it will | ||
// implicitly restore the playing state and send a play request. | ||
_setPlatformActive(true, playCompleter: playCompleter) | ||
?.catchError((dynamic e) {}); | ||
?.catchError((dynamic e) { | ||
_playingSubject.add(false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment applies here.
f3f0c5e
to
94160da
Compare
@ryanheise |
I'm not sure if I fully understand whether this is correct. The original code would only call Did I misunderstand something? |
Ah, probably you are right. So, the problem is that we cannot detect any error on just_audio/just_audio/lib/just_audio.dart Lines 874 to 877 in b1a7d50
I haven't tested anything about this, if the way of correction seems right, I'll test it and update this PR. |
Maybe something like that will work, it's worth a try. |
@ryanheise just_audio/just_audio/lib/just_audio.dart Lines 1496 to 1512 in b5fad79
are caught by A simple fix was to do this instead: } catch (e, stackTrace) {
durationCompleter.completeError(e, stackTrace);
await Future.delayed(Duration.zero);
await _setPlatformActive(false)
?.catchError((dynamic e) async => null);
}
I will try to write an integration test to confirm this. The but the error reporting has been giving me heartache for a while now. |
When play without load like below, no error reported from native platform.
This is because before playbackEventStream reports error, platform is deactivated and the stream is canceled.
The deactivation is caused by error handling on duration report logic in setPlatform.
just_audio/just_audio/lib/just_audio.dart
Line 1356 in 2a22b69
Also fixed stuck in playing after such error occurs.
ref #390