mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-26 17:01:20 -08:00
fix: silence unhandled play() rejections from internal callers
`art.play()` is an async wrapper around the native `video.play()` promise, which rejects when a pending play request is interrupted (`pause()`, `load()`, a new `src`, or the element being removed) and when autoplay is blocked. Every internal caller fires it from an event handler and cannot await it, so the rejection escapes as a global `unhandledrejection`. Error trackers report it as an uncaught crash even though the player recovers on its own — for example destroying the player right after mount, which is routine when the video sits in a modal the user can close quickly. Add a `silencePromise` util (the same approach video.js uses) and apply it to the non-awaited internal call sites: mask, play control, mini player, loop restart, autoPlayback jump, hotkey and click toggles. `switchMix` is fixed too, for a second symptom: `await art.play()` inside the async `video:canplay` handler both leaked the rejection and left the `switchUrl` promise pending forever, since the throw never reached the enclosing executor's `reject`. It now settles. The public API is unchanged: `art.play()` and `art.toggle()` still return the original promise, so applications that call them keep their own rejection to handle. Only the internal, non-awaited copy is silenced.
This commit is contained in:
1 parent
0b9c31a8cf
commit
0f47e11d63
10 files changed
+44
-18
No files matched your search
@@ -1,5 +1,5 @@
|
||||
import config from '../config'
|
||||
import { addClass, isMobile, setStyle, sleep } from '../utils'
|
||||
import { addClass, isMobile, setStyle, silencePromise, sleep } from '../utils'
|
||||
|
||||
export default function eventInit(art) {
|
||||
const {
|
||||
@@ -51,7 +51,7 @@ export default function eventInit(art) {
|
||||
art.on('video:ended', () => {
|
||||
if (option.loop) {
|
||||
art.seek = 0
|
||||
art.play()
|
||||
silencePromise(art.play())
|
||||
art.controls.show = false
|
||||
art.mask.show = false
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { addClass, append, createElement, def, getRect, hasClass, isInViewport, removeClass, setStyle } from '../utils'
|
||||
import { addClass, append, createElement, def, getRect, hasClass, isInViewport, removeClass, setStyle, silencePromise } from '../utils'
|
||||
|
||||
export default function miniMix(art) {
|
||||
const {
|
||||
@@ -53,7 +53,7 @@ export default function miniMix(art) {
|
||||
const $state = append($mini, `<div class="art-mini-state"></div>`)
|
||||
const $play = append($state, icons.play)
|
||||
const $pause = append($state, icons.pause)
|
||||
proxy($play, 'click', () => art.play())
|
||||
proxy($play, 'click', () => silencePromise(art.play()))
|
||||
proxy($pause, 'click', () => art.pause())
|
||||
initState($play, $pause)
|
||||
art.on('video:playing', () => initState($play, $pause))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { def } from '../utils'
|
||||
import { def, silencePromise } from '../utils'
|
||||
|
||||
export default function switchMix(art) {
|
||||
function switchUrl(url, currentTime) {
|
||||
@@ -31,7 +31,7 @@ export default function switchMix(art) {
|
||||
art.aspectRatio = aspectRatio
|
||||
|
||||
if (playing) {
|
||||
await art.play()
|
||||
await silencePromise(art.play())
|
||||
}
|
||||
|
||||
art.notice.show = ''
|
||||
|
||||
Reference in new issue
Block a user