]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/commitdiff
Correctly handle video import errors
authorChocobozzz <me@florianbigard.com>
Fri, 3 Aug 2018 07:27:30 +0000 (09:27 +0200)
committerChocobozzz <me@florianbigard.com>
Mon, 6 Aug 2018 09:19:16 +0000 (11:19 +0200)
client/src/app/+my-account/my-account-video-imports/my-account-video-imports.component.html
client/src/app/+my-account/my-account-video-imports/my-account-video-imports.component.scss
client/src/app/videos/+video-edit/video-import.component.html
server/lib/job-queue/handlers/video-import.ts
server/lib/job-queue/job-queue.ts
server/models/video/video-import.ts
shared/models/videos/video-import.model.ts

index 74ca33fa326f093fc7ba41334c89d9ab5e661e16..00b2d7cb0a810c60193d894bd591030f09ef4c47 100644 (file)
@@ -1,9 +1,10 @@
 <p-table
   [value]="videoImports" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage"
-  [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)"
+  [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" dataKey="id"
 >
   <ng-template pTemplate="header">
     <tr>
+      <th style="width: 40px;"></th>
       <th i18n>URL</th>
       <th i18n>Video</th>
       <th i18n style="width: 150px">State</th>
     </tr>
   </ng-template>
 
-  <ng-template pTemplate="body" let-videoImport>
+  <ng-template pTemplate="body" let-expanded="expanded" let-videoImport>
     <tr>
+      <td>
+        <span *ngIf="videoImport.error" class="expander" [pRowToggler]="videoImport">
+          <i [ngClass]="expanded ? 'glyphicon glyphicon-menu-down' : 'glyphicon glyphicon-menu-right'"></i>
+        </span>
+      </td>
+
       <td>
         <a [href]="videoImport.targetUrl" target="_blank" rel="noopener noreferrer">{{ videoImport.targetUrl }}</a>
       </td>
       </td>
     </tr>
   </ng-template>
+
+  <ng-template pTemplate="rowexpansion" let-videoImport>
+    <tr class="video-import-error" *ngIf="videoImport.error">
+      <td colspan="6">
+        <pre>{{ videoImport.error }}</pre>
+      </td>
+    </tr>
+  </ng-template>
 </p-table>
index 5e6774739fb643993a1068a8f5cc0ab97b73bdfe..bdd2f82701f27cd470c1614d751214623567d474 100644 (file)
@@ -1,2 +1,10 @@
 @import '_variables';
 @import '_mixins';
+
+pre {
+  font-size: 11px;
+}
+
+.video-import-error {
+  color: red;
+}
\ No newline at end of file
index d59c6a23acf2a1920133ac7ff29de253827015a8..cfad5e2896516ddbc3920b8f182b21bdd860f979 100644 (file)
@@ -6,7 +6,7 @@
       <label i18n for="targetUrl">URL</label>
       <my-help
         helpType="custom" i18n-customHtml
-        customHtml="You can import any URL <a href='https://rg3.github.io/youtube-dl/supportedsites.html'>supported by youtube-dl</a> or URL that points to a raw MP4 file. Failure to secure these rights could cause legal trouble to yourself and your instance."
+        customHtml="You can import any URL <a href='https://rg3.github.io/youtube-dl/supportedsites.html' target='_blank' rel='noopener noreferrer'>supported by youtube-dl</a> or URL that points to a raw MP4 file. Failure to secure these rights could cause legal trouble to yourself and your instance."
       ></my-help>
 
       <input type="text" id="targetUrl" [(ngModel)]="targetUrl" />
index 5a7722153d321476bdaafa865b88ffaa1aeebb8c..4f2faab7dfbb650e8047eef51ccf609863ac7d38 100644 (file)
@@ -35,7 +35,7 @@ async function processVideoImport (job: Bull.Job) {
 
     // Get information about this video
     const { videoFileResolution } = await getVideoFileResolution(tempVideoPath)
-    const fps = await getVideoFileFPS(tempVideoPath + 's')
+    const fps = await getVideoFileFPS(tempVideoPath)
     const stats = await statPromise(tempVideoPath)
     const duration = await getDurationFromVideoFile(tempVideoPath)
 
@@ -115,6 +115,7 @@ async function processVideoImport (job: Bull.Job) {
       logger.error('Cannot cleanup files after a video import error.', { err: errUnlink })
     }
 
+    videoImport.error = err.message
     videoImport.state = VideoImportState.FAILED
     await videoImport.save()
 
index 2e14867f247134ce6782b31e0e1268abaac53aa6..ffd948b5f32c57579aa0c2c46c10f7b44643b249 100644 (file)
@@ -79,7 +79,10 @@ class JobQueue {
       const handler = handlers[handlerName]
 
       queue.process(JOB_CONCURRENCY[handlerName], handler)
-        .catch(err => logger.error('Cannot execute job queue %s.', handlerName, { err }))
+
+      queue.on('failed', (job, err) => {
+        logger.error('Cannot execute job %d in queue %s.', job.id, handlerName, { payload: job.data, err })
+      })
 
       queue.on('error', err => {
         logger.error('Error in job queue %s.', handlerName, { err })
index 6b8a16b65302c6eb28149840090e9083657ec47d..c2e55509c128fb75ab0645525afd50092f030c15 100644 (file)
@@ -26,7 +26,7 @@ import { TagModel } from './tag'
   include: [
     {
       model: () => VideoModel,
-      required: true,
+      required: false,
       include: [
         {
           model: () => VideoChannelModel,
@@ -112,7 +112,7 @@ export class VideoImportModel extends Model<VideoImportModel> {
       include: [
         {
           model: VideoModel,
-          required: true,
+          required: false,
           include: [
             {
               model: VideoChannelModel,
@@ -157,11 +157,13 @@ export class VideoImportModel extends Model<VideoImportModel> {
       : undefined
 
     return {
+      id: this.id,
       targetUrl: this.targetUrl,
       state: {
         id: this.state,
         label: VideoImportModel.getStateLabel(this.state)
       },
+      error: this.error,
       updatedAt: this.updatedAt.toISOString(),
       createdAt: this.createdAt.toISOString(),
       video
index b23e6b245e5b5c719ccc448cf99948ab7cbef29f..c8dea0246e2690ccb77727d949fd32d1aaff063e 100644 (file)
@@ -3,10 +3,12 @@ import { VideoConstant } from './video-constant.model'
 import { VideoImportState } from '../../index'
 
 export interface VideoImport {
+  id: number
   targetUrl: string
   createdAt: string
   updatedAt: string
   state: VideoConstant<VideoImportState>
+  error?: string
 
   video?: Video & { tags: string[] }
 }