Bug 1254526 - Don't let Narrate get into bad state after encountering a synth error. r=Gijs
authorEitan Isaacson <eitan@monotonous.org>
Tue, 08 Mar 2016 11:32:40 -0800
changeset 288325 fa1daaba023bb75fcb6fe9509d71a5d658e6d92c
parent 288324 399aee6215e33899a4dfe214f19ecaa6d6fcbb42
child 288326 5b6bcc1fec089df9ab8a72dca6abc9d74b81e12c
push id30079
push userryanvm@gmail.com
push dateSat, 12 Mar 2016 20:24:19 +0000
treeherdermozilla-central@d1d47ba19ce9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersGijs
bugs1254526
milestone48.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1254526 - Don't let Narrate get into bad state after encountering a synth error. r=Gijs MozReview-Commit-ID: GdOgtmM4hGH
toolkit/components/narrate/NarrateControls.jsm
toolkit/components/narrate/Narrator.jsm
--- a/toolkit/components/narrate/NarrateControls.jsm
+++ b/toolkit/components/narrate/NarrateControls.jsm
@@ -143,16 +143,19 @@ NarrateControls.prototype = {
       case "narrate-start-stop":
         if (this.narrator.speaking) {
           this.narrator.stop();
         } else {
           this._updateSpeechControls(true);
           let options = { rate: this.rate, voice: this.voice };
           this.narrator.start(options).then(() => {
             this._updateSpeechControls(false);
+          }, err => {
+            Cu.reportError(`Narrate failed: ${err}.`)
+            this._updateSpeechControls(false);
           });
         }
         break;
       case "narrate-toggle":
         let dropdown = this._doc.getElementById("narrate-dropdown");
         if (dropdown.classList.contains("open")) {
           if (this.narrator.speaking) {
             this.narrator.stop();
--- a/toolkit/components/narrate/Narrator.jsm
+++ b/toolkit/components/narrate/Narrator.jsm
@@ -151,17 +151,17 @@ Narrator.prototype = {
     if (this._speechOptions.voice) {
       utterance.voice = this._speechOptions.voice;
     } else {
       utterance.lang = this._speechOptions.lang;
     }
 
     this._startTime = Date.now();
 
-    return new Promise(resolve => {
+    return new Promise((resolve, reject) => {
       utterance.addEventListener("start", () => {
         paragraph.classList.add("narrating");
         let bb = paragraph.getBoundingClientRect();
         if (bb.top < 0 || bb.bottom > this._win.innerHeight) {
           paragraph.scrollIntoView({ behavior: "smooth", block: "start"});
         }
 
         if (this._inTest) {
@@ -184,20 +184,24 @@ Narrator.prototype = {
         if (this._inTest) {
           this._sendTestEvent("paragraphend", {});
         }
 
         if (this._stopped) {
           // User pressed stopped.
           resolve();
         } else {
-          this._speakInner().then(resolve);
+          this._speakInner().then(resolve, reject);
         }
       });
 
+      utterance.addEventListener("error", () => {
+        reject("speech synthesis failed")
+      });
+
       this._win.speechSynthesis.speak(utterance);
     });
   },
 
   getVoiceOptions: function() {
     return Array.from(this._voiceMap.values());
   },