« get me outta code hell

Handle failed downloads in loop-play - http-music - Command-line music player + utils (not a server!)
about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFlorrie <towerofnix@gmail.com>2017-08-04 12:51:22 -0300
committerFlorrie <towerofnix@gmail.com>2017-08-04 12:51:22 -0300
commit3b62e1aefa8606165f60e4ae269e4b90d43bac40 (patch)
tree5d6b484b81301c18b2b50cc21c07d2b10e2e5d1a
parente9d81816c01bdfe874ed04f1d702302a92f66bf1 (diff)
Handle failed downloads in loop-play
-rw-r--r--src/loop-play.js41
-rw-r--r--todo.txt1
2 files changed, 32 insertions, 10 deletions
diff --git a/src/loop-play.js b/src/loop-play.js
index 9328073..5690f9b 100644
--- a/src/loop-play.js
+++ b/src/loop-play.js
@@ -21,8 +21,17 @@ class DownloadController extends EventEmitter {
     // been canceled (see cancel).  You can also listen for the
     // 'downloaded' event instead.
 
-    return new Promise(resolve => {
-      this.once('downloaded', file => resolve(file))
+    return new Promise((resolve, reject) => {
+      const onDownloaded = file => { clear(); resolve(file) }
+      const onErrored = err => { clear(); reject(err) }
+
+      const clear = () => {
+        this.removeListener('downloaded', onDownloaded)
+        this.removeListener('errored', onErrored)
+      }
+
+      this.once('downloaded', onDownloaded)
+      this.once('errored', onErrored)
     })
   }
 
@@ -44,7 +53,14 @@ class DownloadController extends EventEmitter {
 
     this.once('canceled', this._handleCanceled)
 
-    const file = await downloader(arg)
+    let file
+
+    try {
+      file = await downloader(arg)
+    } catch(err) {
+      this.emit('errored', err)
+      return
+    }
 
     if (!canceled) {
       this.emit('downloaded', file)
@@ -80,19 +96,24 @@ class PlayController {
   async loopPlay() {
     let nextFile
 
-    // Null would imply there's NO up-next track, but really
-    // we just haven't set it yet.
+    // Null would imply there's NO up-next track, but really we just haven't
+    // set it yet.
     this.nextTrack = undefined
 
-    let downloadNext = () => {
+    const downloadNext = async () => {
       this.nextTrack = this.startNextDownload()
       if (this.nextTrack !== null) {
-        return this.downloadController.waitForDownload().then(file => {
-          nextFile = file
-        })
+        try {
+          nextFile = await this.downloadController.waitForDownload()
+        } catch(err) {
+          console.warn(
+            "\x1b[31mFailed to download (or convert) track \x1b[1m" +
+            getItemPathString(this.nextTrack) + "\x1b[0m"
+          )
+          await downloadNext()
+        }
       } else {
         nextFile = null
-        return Promise.resolve()
       }
     }
 
diff --git a/todo.txt b/todo.txt
index d3ddeb1..f4bd4fd 100644
--- a/todo.txt
+++ b/todo.txt
@@ -260,3 +260,4 @@ TODO: Handle avconv failing (probably handle downloader rejections from within
       DownloadController). Less important now that only music file extensions
       are loaded, but still relevant (for old playlists which may contain
       .DS_Stores or album cover arts, etc).
+      (Done!)