# HG changeset patch # User Daisuke Akatsuka # Date 1521509672 -32400 # Node ID 7f2fcbb2e2b9befefb6740ecf87153d9522da446 # Parent e5b85c645cda5b20d064c336d22f12fae1eae274 Bug 1445291: Handle to the error 'no such actor'. r=gl diff --git a/devtools/client/inspector/animation/animation.js b/devtools/client/inspector/animation/animation.js --- a/devtools/client/inspector/animation/animation.js +++ b/devtools/client/inspector/animation/animation.js @@ -186,25 +186,18 @@ class AnimationInspector { * { * value: {String} style, * offset: {Number} offset of keyframe, * easing: {String} easing from this keyframe to next keyframe, * distance: {Number} use as y coordinate in graph, * } */ async getAnimatedPropertyMap(animation) { - let properties = []; - - try { - properties = await animation.getProperties(); - } catch (e) { - // Expected if we've already been destroyed in the meantime. - console.error(e); - } - + // getProperties might throw an error. + const properties = await animation.getProperties(); const animatedPropertyMap = new Map(); for (const { name, values } of properties) { const keyframes = values.map(({ value, offset, easing, distance = 0 }) => { offset = parseFloat(offset.toFixed(3)); return { value, offset, easing, distance }; }); @@ -317,40 +310,66 @@ class AnimationInspector { this.onAnimationsCurrentTimeUpdated(currentTime); if (!shouldRefresh && this.isCurrentTimeSet) { return; } const animations = this.state.animations; this.isCurrentTimeSet = true; - await this.animationsFront.setCurrentTimes(animations, currentTime, true); - await this.updateAnimations(animations); + + try { + await this.animationsFront.setCurrentTimes(animations, currentTime, true); + await this.updateAnimations(animations); + } catch (e) { + // Expected if we've already been destroyed or other node have been selected + // in the meantime. + console.error(e); + return; + } + this.isCurrentTimeSet = false; if (shouldRefresh) { this.updateState([...animations]); } } async setAnimationsPlaybackRate(playbackRate) { const animations = this.state.animations; - await this.animationsFront.setPlaybackRates(animations, playbackRate); - await this.updateAnimations(animations); + + try { + await this.animationsFront.setPlaybackRates(animations, playbackRate); + await this.updateAnimations(animations); + } catch (e) { + // Expected if we've already been destroyed or other node have been selected + // in the meantime. + console.error(e); + return; + } + await this.updateState([...animations]); } async setAnimationsPlayState(doPlay) { - if (doPlay) { - await this.animationsFront.playAll(); - } else { - await this.animationsFront.pauseAll(); + try { + if (doPlay) { + await this.animationsFront.playAll(); + } else { + await this.animationsFront.pauseAll(); + } + + await this.updateAnimations(this.state.animations); + } catch (e) { + // Expected if we've already been destroyed or other node have been selected + // in the meantime. + console.error(e); + return; } - await this.updateAnimations(this.state.animations); await this.updateState([...this.state.animations]); } setDetailVisibility(isVisible) { this.inspector.store.dispatch(updateDetailVisibility(isVisible)); } /** @@ -456,22 +475,37 @@ class AnimationInspector { if (!currentAnimations || !isAllAnimationEqual(currentAnimations, nextAnimations)) { this.updateState(nextAnimations); } done(); } - async updateAnimations(animations) { - const promises = animations.map(animation => { - return animation.refreshState(); + updateAnimations(animations) { + return new Promise((resolve, reject) => { + let count = 0; + let error = null; + + for (const animation of animations) { + animation.refreshState().catch(e => { + error = e; + }).finally(() => { + count += 1; + + if (count === animations.length) { + if (error) { + reject(error); + } else { + resolve(); + } + } + }); + } }); - - await Promise.all(promises); } updateState(animations) { this.stopAnimationsCurrentTimeTimer(); this.inspector.store.dispatch(updateAnimations(animations)); if (hasRunningAnimation(animations)) { diff --git a/devtools/client/inspector/animation/components/AnimatedPropertyList.js b/devtools/client/inspector/animation/components/AnimatedPropertyList.js --- a/devtools/client/inspector/animation/components/AnimatedPropertyList.js +++ b/devtools/client/inspector/animation/components/AnimatedPropertyList.js @@ -49,21 +49,31 @@ class AnimatedPropertyList extends PureC return null; } async updateKeyframesList(animation) { const { getAnimatedPropertyMap, emitEventForTest, } = this.props; - const animatedPropertyMap = await getAnimatedPropertyMap(animation); - const animationTypes = await animation.getAnimationTypes(animatedPropertyMap.keys()); + + let animatedPropertyMap = null; + let animationTypes = null; + + try { + animatedPropertyMap = await getAnimatedPropertyMap(animation); + animationTypes = await animation.getAnimationTypes(animatedPropertyMap.keys()); + } catch (e) { + // Expected if we've already been destroyed or other node have been selected + // in the meantime. + console.error(e); + return; + } this.setState({ animatedPropertyMap, animationTypes }); - emitEventForTest("animation-keyframes-rendered"); } render() { const { getComputedStyle, simulateAnimation, } = this.props; diff --git a/devtools/client/inspector/animation/components/graph/SummaryGraphPath.js b/devtools/client/inspector/animation/components/graph/SummaryGraphPath.js --- a/devtools/client/inspector/animation/components/graph/SummaryGraphPath.js +++ b/devtools/client/inspector/animation/components/graph/SummaryGraphPath.js @@ -143,17 +143,27 @@ class SummaryGraphPath extends PureCompo async updateState(animation) { const { emitEventForTest, getAnimatedPropertyMap, timeScale, } = this.props; - const animatedPropertyMap = await getAnimatedPropertyMap(animation); + let animatedPropertyMap = null; + + try { + animatedPropertyMap = await getAnimatedPropertyMap(animation); + } catch (e) { + // Expected if we've already been destroyed or other node have been selected + // in the meantime. + console.error(e); + return; + } + const keyframesList = this.getOffsetAndEasingOnlyKeyframes(animatedPropertyMap); const thisEl = ReactDOM.findDOMNode(this); const totalDuration = this.getTotalDuration(animation, timeScale); const durationPerPixel = totalDuration / thisEl.parentNode.clientWidth; this.setState({ durationPerPixel, keyframesList });