diff options
author | Rigel Kent <sendmemail@rigelk.eu> | 2020-12-08 21:16:10 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-08 21:16:10 +0100 |
commit | f2eb23cd87cf32b8fe545178143b5f49e06a58da (patch) | |
tree | af7d59945af70e28fd85047e2c688c59a908f548 /client/src/app | |
parent | c977fd3ec931c059111ddb2b8d6ddbb20b6b99a1 (diff) | |
download | PeerTube-f2eb23cd87cf32b8fe545178143b5f49e06a58da.tar.gz PeerTube-f2eb23cd87cf32b8fe545178143b5f49e06a58da.tar.zst PeerTube-f2eb23cd87cf32b8fe545178143b5f49e06a58da.zip |
emit more specific status codes on video upload (#3423)
- reduce http status codes list to potentially useful codes
- convert more codes to typed ones
- factorize html generator for error responses
Diffstat (limited to 'client/src/app')
8 files changed, 56 insertions, 20 deletions
diff --git a/client/src/app/+about/about-instance/contact-admin-modal.component.ts b/client/src/app/+about/about-instance/contact-admin-modal.component.ts index 11e442f6b..ac2a6c980 100644 --- a/client/src/app/+about/about-instance/contact-admin-modal.component.ts +++ b/client/src/app/+about/about-instance/contact-admin-modal.component.ts | |||
@@ -10,6 +10,7 @@ import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' | |||
10 | import { InstanceService } from '@app/shared/shared-instance' | 10 | import { InstanceService } from '@app/shared/shared-instance' |
11 | import { NgbModal } from '@ng-bootstrap/ng-bootstrap' | 11 | import { NgbModal } from '@ng-bootstrap/ng-bootstrap' |
12 | import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' | 12 | import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' |
13 | import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' | ||
13 | import { ServerConfig } from '@shared/models' | 14 | import { ServerConfig } from '@shared/models' |
14 | 15 | ||
15 | @Component({ | 16 | @Component({ |
@@ -78,7 +79,7 @@ export class ContactAdminModalComponent extends FormReactive implements OnInit { | |||
78 | }, | 79 | }, |
79 | 80 | ||
80 | err => { | 81 | err => { |
81 | this.error = err.status === 403 | 82 | this.error = err.status === HttpStatusCode.FORBIDDEN_403 |
82 | ? $localize`You already sent this form recently` | 83 | ? $localize`You already sent this form recently` |
83 | : err.message | 84 | : err.message |
84 | } | 85 | } |
diff --git a/client/src/app/+accounts/accounts.component.ts b/client/src/app/+accounts/accounts.component.ts index dbc7c8887..4820eaf32 100644 --- a/client/src/app/+accounts/accounts.component.ts +++ b/client/src/app/+accounts/accounts.component.ts | |||
@@ -6,6 +6,7 @@ import { AuthService, Notifier, RedirectService, RestExtractor, ScreenService, U | |||
6 | import { Account, AccountService, DropdownAction, ListOverflowItem, VideoChannel, VideoChannelService } from '@app/shared/shared-main' | 6 | import { Account, AccountService, DropdownAction, ListOverflowItem, VideoChannel, VideoChannelService } from '@app/shared/shared-main' |
7 | import { AccountReportComponent } from '@app/shared/shared-moderation' | 7 | import { AccountReportComponent } from '@app/shared/shared-moderation' |
8 | import { User, UserRight } from '@shared/models' | 8 | import { User, UserRight } from '@shared/models' |
9 | import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' | ||
9 | 10 | ||
10 | @Component({ | 11 | @Component({ |
11 | templateUrl: './accounts.component.html', | 12 | templateUrl: './accounts.component.html', |
@@ -47,7 +48,10 @@ export class AccountsComponent implements OnInit, OnDestroy { | |||
47 | switchMap(accountId => this.accountService.getAccount(accountId)), | 48 | switchMap(accountId => this.accountService.getAccount(accountId)), |
48 | tap(account => this.onAccount(account)), | 49 | tap(account => this.onAccount(account)), |
49 | switchMap(account => this.videoChannelService.listAccountVideoChannels(account)), | 50 | switchMap(account => this.videoChannelService.listAccountVideoChannels(account)), |
50 | catchError(err => this.restExtractor.redirectTo404IfNotFound(err, [ 400, 404 ])) | 51 | catchError(err => this.restExtractor.redirectTo404IfNotFound(err, [ |
52 | HttpStatusCode.BAD_REQUEST_400, | ||
53 | HttpStatusCode.NOT_FOUND_404 | ||
54 | ])) | ||
51 | ) | 55 | ) |
52 | .subscribe( | 56 | .subscribe( |
53 | videoChannels => this.videoChannels = videoChannels.data, | 57 | videoChannels => this.videoChannels = videoChannels.data, |
diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channel-create.component.ts b/client/src/app/+my-library/+my-video-channels/my-video-channel-create.component.ts index 1d0cbf246..a625493de 100644 --- a/client/src/app/+my-library/+my-video-channels/my-video-channel-create.component.ts +++ b/client/src/app/+my-library/+my-video-channels/my-video-channel-create.component.ts | |||
@@ -10,6 +10,7 @@ import { | |||
10 | import { FormValidatorService } from '@app/shared/shared-forms' | 10 | import { FormValidatorService } from '@app/shared/shared-forms' |
11 | import { VideoChannelService } from '@app/shared/shared-main' | 11 | import { VideoChannelService } from '@app/shared/shared-main' |
12 | import { VideoChannelCreate } from '@shared/models' | 12 | import { VideoChannelCreate } from '@shared/models' |
13 | import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' | ||
13 | import { MyVideoChannelEdit } from './my-video-channel-edit' | 14 | import { MyVideoChannelEdit } from './my-video-channel-edit' |
14 | 15 | ||
15 | @Component({ | 16 | @Component({ |
@@ -58,7 +59,7 @@ export class MyVideoChannelCreateComponent extends MyVideoChannelEdit implements | |||
58 | }, | 59 | }, |
59 | 60 | ||
60 | err => { | 61 | err => { |
61 | if (err.status === 409) { | 62 | if (err.status === HttpStatusCode.CONFLICT_409) { |
62 | this.error = $localize`This name already exists on this instance.` | 63 | this.error = $localize`This name already exists on this instance.` |
63 | return | 64 | return |
64 | } | 65 | } |
diff --git a/client/src/app/+video-channels/video-channels.component.ts b/client/src/app/+video-channels/video-channels.component.ts index ea8bda1cf..d2fd265c4 100644 --- a/client/src/app/+video-channels/video-channels.component.ts +++ b/client/src/app/+video-channels/video-channels.component.ts | |||
@@ -6,6 +6,7 @@ import { ActivatedRoute } from '@angular/router' | |||
6 | import { AuthService, Notifier, RestExtractor, ScreenService } from '@app/core' | 6 | import { AuthService, Notifier, RestExtractor, ScreenService } from '@app/core' |
7 | import { ListOverflowItem, VideoChannel, VideoChannelService } from '@app/shared/shared-main' | 7 | import { ListOverflowItem, VideoChannel, VideoChannelService } from '@app/shared/shared-main' |
8 | import { SubscribeButtonComponent } from '@app/shared/shared-user-subscription' | 8 | import { SubscribeButtonComponent } from '@app/shared/shared-user-subscription' |
9 | import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' | ||
9 | 10 | ||
10 | @Component({ | 11 | @Component({ |
11 | templateUrl: './video-channels.component.html', | 12 | templateUrl: './video-channels.component.html', |
@@ -37,7 +38,10 @@ export class VideoChannelsComponent implements OnInit, OnDestroy { | |||
37 | map(params => params[ 'videoChannelName' ]), | 38 | map(params => params[ 'videoChannelName' ]), |
38 | distinctUntilChanged(), | 39 | distinctUntilChanged(), |
39 | switchMap(videoChannelName => this.videoChannelService.getVideoChannel(videoChannelName)), | 40 | switchMap(videoChannelName => this.videoChannelService.getVideoChannel(videoChannelName)), |
40 | catchError(err => this.restExtractor.redirectTo404IfNotFound(err, [ 400, 404 ])) | 41 | catchError(err => this.restExtractor.redirectTo404IfNotFound(err, [ |
42 | HttpStatusCode.BAD_REQUEST_400, | ||
43 | HttpStatusCode.NOT_FOUND_404 | ||
44 | ])) | ||
41 | ) | 45 | ) |
42 | .subscribe(videoChannel => { | 46 | .subscribe(videoChannel => { |
43 | this.videoChannel = videoChannel | 47 | this.videoChannel = videoChannel |
diff --git a/client/src/app/+videos/+video-edit/video-add-components/video-upload.component.ts b/client/src/app/+videos/+video-edit/video-add-components/video-upload.component.ts index bee3679f7..cafb030b9 100644 --- a/client/src/app/+videos/+video-edit/video-add-components/video-upload.component.ts +++ b/client/src/app/+videos/+video-edit/video-add-components/video-upload.component.ts | |||
@@ -9,6 +9,7 @@ import { BytesPipe, VideoCaptionService, VideoEdit, VideoService } from '@app/sh | |||
9 | import { LoadingBarService } from '@ngx-loading-bar/core' | 9 | import { LoadingBarService } from '@ngx-loading-bar/core' |
10 | import { VideoPrivacy } from '@shared/models' | 10 | import { VideoPrivacy } from '@shared/models' |
11 | import { VideoSend } from './video-send' | 11 | import { VideoSend } from './video-send' |
12 | import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' | ||
12 | 13 | ||
13 | @Component({ | 14 | @Component({ |
14 | selector: 'my-video-upload', | 15 | selector: 'my-video-upload', |
@@ -129,17 +130,17 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy | |||
129 | cancelUpload () { | 130 | cancelUpload () { |
130 | if (this.videoUploadObservable !== null) { | 131 | if (this.videoUploadObservable !== null) { |
131 | this.videoUploadObservable.unsubscribe() | 132 | this.videoUploadObservable.unsubscribe() |
133 | } | ||
132 | 134 | ||
133 | this.isUploadingVideo = false | 135 | this.isUploadingVideo = false |
134 | this.videoUploadPercents = 0 | 136 | this.videoUploadPercents = 0 |
135 | this.videoUploadObservable = null | 137 | this.videoUploadObservable = null |
136 | 138 | ||
137 | this.firstStepError.emit() | 139 | this.firstStepError.emit() |
138 | this.enableRetryAfterError = false | 140 | this.enableRetryAfterError = false |
139 | this.error = '' | 141 | this.error = '' |
140 | 142 | ||
141 | this.notifier.info($localize`Upload cancelled`) | 143 | this.notifier.info($localize`Upload cancelled`) |
142 | } | ||
143 | } | 144 | } |
144 | 145 | ||
145 | uploadFirstStep (clickedOnButton = false) { | 146 | uploadFirstStep (clickedOnButton = false) { |
@@ -229,6 +230,11 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy | |||
229 | notifier: this.notifier, | 230 | notifier: this.notifier, |
230 | sticky: false | 231 | sticky: false |
231 | }) | 232 | }) |
233 | |||
234 | if (err.status === HttpStatusCode.PAYLOAD_TOO_LARGE_413 || | ||
235 | err.status === HttpStatusCode.UNSUPPORTED_MEDIA_TYPE_415) { | ||
236 | this.cancelUpload() | ||
237 | } | ||
232 | } | 238 | } |
233 | ) | 239 | ) |
234 | } | 240 | } |
diff --git a/client/src/app/+videos/+video-watch/video-watch.component.ts b/client/src/app/+videos/+video-watch/video-watch.component.ts index b15de2a79..33de901c0 100644 --- a/client/src/app/+videos/+video-watch/video-watch.component.ts +++ b/client/src/app/+videos/+video-watch/video-watch.component.ts | |||
@@ -39,6 +39,7 @@ import { isWebRTCDisabled, timeToInt } from '../../../assets/player/utils' | |||
39 | import { environment } from '../../../environments/environment' | 39 | import { environment } from '../../../environments/environment' |
40 | import { VideoSupportComponent } from './modal/video-support.component' | 40 | import { VideoSupportComponent } from './modal/video-support.component' |
41 | import { VideoWatchPlaylistComponent } from './video-watch-playlist.component' | 41 | import { VideoWatchPlaylistComponent } from './video-watch-playlist.component' |
42 | import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' | ||
42 | 43 | ||
43 | type URLOptions = CustomizationOptions & { playerMode: PlayerMode } | 44 | type URLOptions = CustomizationOptions & { playerMode: PlayerMode } |
44 | 45 | ||
@@ -412,13 +413,25 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
412 | $localize`This video is not available on this instance. Do you want to be redirected on the origin instance: <a href="${originUrl}">${originUrl}</a>?`, | 413 | $localize`This video is not available on this instance. Do you want to be redirected on the origin instance: <a href="${originUrl}">${originUrl}</a>?`, |
413 | $localize`Redirection` | 414 | $localize`Redirection` |
414 | ).then(res => { | 415 | ).then(res => { |
415 | if (res === false) return this.restExtractor.redirectTo404IfNotFound(err, [ 400, 401, 403, 404 ]) | 416 | if (res === false) { |
417 | return this.restExtractor.redirectTo404IfNotFound(err, [ | ||
418 | HttpStatusCode.BAD_REQUEST_400, | ||
419 | HttpStatusCode.UNAUTHORIZED_401, | ||
420 | HttpStatusCode.FORBIDDEN_403, | ||
421 | HttpStatusCode.NOT_FOUND_404 | ||
422 | ]) | ||
423 | } | ||
416 | 424 | ||
417 | return window.location.href = originUrl | 425 | return window.location.href = originUrl |
418 | }) | 426 | }) |
419 | } | 427 | } |
420 | 428 | ||
421 | return this.restExtractor.redirectTo404IfNotFound(err, [ 400, 401, 403, 404 ]) | 429 | return this.restExtractor.redirectTo404IfNotFound(err, [ |
430 | HttpStatusCode.BAD_REQUEST_400, | ||
431 | HttpStatusCode.UNAUTHORIZED_401, | ||
432 | HttpStatusCode.FORBIDDEN_403, | ||
433 | HttpStatusCode.NOT_FOUND_404 | ||
434 | ]) | ||
422 | }) | 435 | }) |
423 | ) | 436 | ) |
424 | .subscribe(([ video, captionsResult ]) => { | 437 | .subscribe(([ video, captionsResult ]) => { |
@@ -450,7 +463,12 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
450 | this.playlistService.getVideoPlaylist(playlistId) | 463 | this.playlistService.getVideoPlaylist(playlistId) |
451 | .pipe( | 464 | .pipe( |
452 | // If 401, the video is private or blocked so redirect to 404 | 465 | // If 401, the video is private or blocked so redirect to 404 |
453 | catchError(err => this.restExtractor.redirectTo404IfNotFound(err, [ 400, 401, 403, 404 ])) | 466 | catchError(err => this.restExtractor.redirectTo404IfNotFound(err, [ |
467 | HttpStatusCode.BAD_REQUEST_400, | ||
468 | HttpStatusCode.UNAUTHORIZED_401, | ||
469 | HttpStatusCode.FORBIDDEN_403, | ||
470 | HttpStatusCode.NOT_FOUND_404 | ||
471 | ])) | ||
454 | ) | 472 | ) |
455 | .subscribe(playlist => { | 473 | .subscribe(playlist => { |
456 | this.playlist = playlist | 474 | this.playlist = playlist |
diff --git a/client/src/app/core/auth/auth.service.ts b/client/src/app/core/auth/auth.service.ts index fd6062d3f..cdf13186b 100644 --- a/client/src/app/core/auth/auth.service.ts +++ b/client/src/app/core/auth/auth.service.ts | |||
@@ -11,6 +11,7 @@ import { environment } from '../../../environments/environment' | |||
11 | import { RestExtractor } from '../rest/rest-extractor.service' | 11 | import { RestExtractor } from '../rest/rest-extractor.service' |
12 | import { AuthStatus } from './auth-status.model' | 12 | import { AuthStatus } from './auth-status.model' |
13 | import { AuthUser } from './auth-user.model' | 13 | import { AuthUser } from './auth-user.model' |
14 | import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' | ||
14 | 15 | ||
15 | interface UserLoginWithUsername extends UserLogin { | 16 | interface UserLoginWithUsername extends UserLogin { |
16 | access_token: string | 17 | access_token: string |
@@ -94,7 +95,7 @@ export class AuthService { | |||
94 | error => { | 95 | error => { |
95 | let errorMessage = error.message | 96 | let errorMessage = error.message |
96 | 97 | ||
97 | if (error.status === 403) { | 98 | if (error.status === HttpStatusCode.FORBIDDEN_403) { |
98 | errorMessage = $localize`Cannot retrieve OAuth Client credentials: ${error.text}. | 99 | errorMessage = $localize`Cannot retrieve OAuth Client credentials: ${error.text}. |
99 | Ensure you have correctly configured PeerTube (config/ directory), in particular the "webserver" section.` | 100 | Ensure you have correctly configured PeerTube (config/ directory), in particular the "webserver" section.` |
100 | } | 101 | } |
diff --git a/client/src/app/core/rest/rest-extractor.service.ts b/client/src/app/core/rest/rest-extractor.service.ts index 4b8c1e155..84d9ed074 100644 --- a/client/src/app/core/rest/rest-extractor.service.ts +++ b/client/src/app/core/rest/rest-extractor.service.ts | |||
@@ -3,6 +3,7 @@ import { Injectable } from '@angular/core' | |||
3 | import { Router } from '@angular/router' | 3 | import { Router } from '@angular/router' |
4 | import { dateToHuman } from '@app/helpers' | 4 | import { dateToHuman } from '@app/helpers' |
5 | import { ResultList } from '@shared/models' | 5 | import { ResultList } from '@shared/models' |
6 | import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' | ||
6 | 7 | ||
7 | @Injectable() | 8 | @Injectable() |
8 | export class RestExtractor { | 9 | export class RestExtractor { |
@@ -57,9 +58,9 @@ export class RestExtractor { | |||
57 | errorMessage = errorsArray.join('. ') | 58 | errorMessage = errorsArray.join('. ') |
58 | } else if (err.error && err.error.error) { | 59 | } else if (err.error && err.error.error) { |
59 | errorMessage = err.error.error | 60 | errorMessage = err.error.error |
60 | } else if (err.status === 413) { | 61 | } else if (err.status === HttpStatusCode.PAYLOAD_TOO_LARGE_413) { |
61 | errorMessage = $localize`Media is too large for the server. Please contact you administrator if you want to increase the limit size.` | 62 | errorMessage = $localize`Media is too large for the server. Please contact you administrator if you want to increase the limit size.` |
62 | } else if (err.status === 429) { | 63 | } else if (err.status === HttpStatusCode.TOO_MANY_REQUESTS_429) { |
63 | const secondsLeft = err.headers.get('retry-after') | 64 | const secondsLeft = err.headers.get('retry-after') |
64 | if (secondsLeft) { | 65 | if (secondsLeft) { |
65 | const minutesLeft = Math.floor(parseInt(secondsLeft, 10) / 60) | 66 | const minutesLeft = Math.floor(parseInt(secondsLeft, 10) / 60) |
@@ -67,7 +68,7 @@ export class RestExtractor { | |||
67 | } else { | 68 | } else { |
68 | errorMessage = $localize`Too many attempts, please try again later.` | 69 | errorMessage = $localize`Too many attempts, please try again later.` |
69 | } | 70 | } |
70 | } else if (err.status === 500) { | 71 | } else if (err.status === HttpStatusCode.INTERNAL_SERVER_ERROR_500) { |
71 | errorMessage = $localize`Server error. Please retry later.` | 72 | errorMessage = $localize`Server error. Please retry later.` |
72 | } | 73 | } |
73 | 74 | ||
@@ -92,7 +93,7 @@ export class RestExtractor { | |||
92 | return observableThrowError(errorObj) | 93 | return observableThrowError(errorObj) |
93 | } | 94 | } |
94 | 95 | ||
95 | redirectTo404IfNotFound (obj: { status: number }, status = [ 404 ]) { | 96 | redirectTo404IfNotFound (obj: { status: number }, status = [ HttpStatusCode.NOT_FOUND_404 ]) { |
96 | if (obj && obj.status && status.indexOf(obj.status) !== -1) { | 97 | if (obj && obj.status && status.indexOf(obj.status) !== -1) { |
97 | // Do not use redirectService to avoid circular dependencies | 98 | // Do not use redirectService to avoid circular dependencies |
98 | this.router.navigate([ '/404' ], { skipLocationChange: true }) | 99 | this.router.navigate([ '/404' ], { skipLocationChange: true }) |