Correctly handle error when remote instance is down
authorChocobozzz <me@florianbigard.com>
Mon, 16 Jul 2018 17:15:20 +0000 (19:15 +0200)
committerChocobozzz <me@florianbigard.com>
Mon, 16 Jul 2018 17:15:20 +0000 (19:15 +0200)
client/src/app/videos/+video-watch/video-watch.component.html
client/src/app/videos/+video-watch/video-watch.component.scss
client/src/app/videos/+video-watch/video-watch.component.ts
client/src/assets/player/peertube-videojs-plugin.ts
client/src/standalone/videos/embed.scss
client/src/standalone/videos/embed.ts

index f28134ece2a1615075cb181e0401cdde2bacfc98..21f8f55344910d70f51090a00d9c2316e284f0c6 100644 (file)
@@ -1,6 +1,11 @@
 <div class="row">
   <!-- We need the video container for videojs so we just hide it -->
   <div id="video-element-wrapper">
+    <div *ngIf="remoteServerDown" class="remote-server-down">
+      Sorry, but this video is not available because the remote instance is not responding.
+      <br />
+      Please try again later.
+    </div>
   </div>
 
   <div i18n class="alert alert-warning" *ngIf="isVideoToTranscode()">
index 7c694f2e2724c09e47579350c5c36e21a852fd33..4ce17209f4003f6c8db2ca93fa5c732e99813245 100644 (file)
@@ -5,15 +5,37 @@
   background-color: #000;
   display: flex;
   justify-content: center;
+  height: 500px;
 
-  /deep/ .video-js {
-    width: 888px;
-    height: 500px;
+  @media screen and (max-width: 600px) {
+    width: 100vw;
+    height: calc(100vw / 1.7); // 16/9
+  }
+
+  .remote-server-down {
+    color: #fff;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    text-align: center;
+    justify-content: center;
+    background-color: #141313;
+    width: 100%;
+    height: 100%;
+    font-size: 24px;
+
+    @media screen and (max-width: 1000px) {
+      font-size: 20px;
+    }
 
     @media screen and (max-width: 600px) {
-      width: 100vw;
-      height: calc(100vw / 1.7); // 16/9
+      font-size: 16px;
     }
+  }
+
+  /deep/ .video-js {
+    width: 888px;
+    height: 100%;
 
     // VideoJS create an inner video player
     video {
index 601c6a38da342803f9e3d016dc52490e981cdcc6..43afbae1a19261df7b159a24d7710eb12e06f3b3 100644 (file)
@@ -57,6 +57,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
   videoHTMLDescription = ''
   likesBarTooltipText = ''
   hasAlreadyAcceptedPrivacyConcern = false
+  remoteServerDown = false
 
   private videojsLocaleLoaded = false
   private otherVideos: Video[] = []
@@ -312,15 +313,14 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
     const errorMessage: string = typeof err === 'string' ? err : err.message
     if (!errorMessage) return
 
-    let message = ''
-
+    // Display a message in the video player instead of a notification
     if (errorMessage.indexOf('http error') !== -1) {
-      message = this.i18n('Cannot fetch video from server, maybe down.')
-    } else {
-      message = errorMessage
+      this.flushPlayer()
+      this.remoteServerDown = true
+      return
     }
 
-    this.notificationsService.error(this.i18n('Error'), message)
+    this.notificationsService.error(this.i18n('Error'), errorMessage)
   }
 
   private checkUserRating () {
@@ -345,6 +345,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
     // Re init attributes
     this.descriptionLoading = false
     this.completeDescriptionShown = false
+    this.remoteServerDown = false
 
     this.updateOtherVideosDisplayed()
 
index 0dcbe49b19a402438a0e054c5844c22691b6d401..6d96e1c0b2121cda9307104a5a69619078f5dd66 100644 (file)
@@ -268,7 +268,12 @@ class PeerTubePlugin extends Plugin {
         return this.addTorrent(this.torrent['xs'], previousVideoFile, newOptions, done)
       }
 
-      return console.warn(err)
+      // Remote instance is down
+      if (err.message.indexOf('http error from xs param') !== -1) {
+        this.handleError(err)
+      }
+
+      console.warn(err)
     })
   }
 
index f92a1f54a37c66289010eb764227248384f80a39..30650538fcf125907495482b530919961bcc9790 100644 (file)
@@ -63,7 +63,6 @@ html, body {
   align-content: center;
   justify-content: center;
   text-align: center;
-  background-color: #141313;
   width: 100%;
   height: 100%;
   color: white;
index b2809467d9888d078b8dc7fad7e9d00542387782..cb05ec2b56d72e0b100393e1eb20e158ef67423a 100644 (file)
@@ -188,9 +188,9 @@ class PeerTubeEmbed {
     element.parentElement.removeChild(element)
   }
 
-  displayError (videoElement: HTMLVideoElement, text: string) {
+  displayError (text: string) {
     // Remove video element
-    this.removeElement(videoElement)
+    if (this.videoElement) this.removeElement(this.videoElement)
 
     document.title = 'Sorry - ' + text
 
@@ -201,14 +201,14 @@ class PeerTubeEmbed {
     errorText.innerHTML = text
   }
 
-  videoNotFound (videoElement: HTMLVideoElement) {
+  videoNotFound () {
     const text = 'This video does not exist.'
-    this.displayError(videoElement, text)
+    this.displayError(text)
   }
 
-  videoFetchError (videoElement: HTMLVideoElement) {
+  videoFetchError () {
     const text = 'We cannot fetch the video. Please try again later.'
-    this.displayError(videoElement, text)
+    this.displayError(text)
   }
 
   getParamToggle (params: URLSearchParams, name: string, defaultValue: boolean) {
@@ -264,9 +264,9 @@ class PeerTubeEmbed {
     ])
 
     if (!videoResponse.ok) {
-      if (videoResponse.status === 404) return this.videoNotFound(this.videoElement)
+      if (videoResponse.status === 404) return this.videoNotFound()
 
-      return this.videoFetchError(this.videoElement)
+      return this.videoFetchError()
     }
 
     const videoInfo: VideoDetails = await videoResponse.json()
@@ -303,6 +303,7 @@ class PeerTubeEmbed {
 
     this.playerOptions = videojsOptions
     this.player = vjs(this.videoContainerId, videojsOptions, () => {
+      this.player.on('customError', (event, data) => this.handleError(data.err))
 
       window[ 'videojsPlayer' ] = this.player
 
@@ -318,6 +319,15 @@ class PeerTubeEmbed {
       this.initializeApi()
     })
   }
+
+  private handleError (err: Error) {
+    if (err.message.indexOf('http error') !== -1) {
+      this.player.dispose()
+      this.videoElement = null
+      this.displayError('This video is not available because the remote instance is not responding.')
+      return
+    }
+  }
 }
 
 PeerTubeEmbed.main()