From 76148b27f7501bac061992136852be4303370c8d Mon Sep 17 00:00:00 2001 From: Rigel Kent Date: Tue, 1 Jun 2021 01:36:53 +0200 Subject: refactor API errors to standard error format --- server/controllers/api/abuse.ts | 6 +++--- server/controllers/api/bulk.ts | 2 +- server/controllers/api/custom-page.ts | 9 +++++++-- server/controllers/api/oauth-clients.ts | 5 ++++- server/controllers/api/plugins.ts | 14 ++++++++------ server/controllers/api/search.ts | 10 ++++++++-- server/controllers/api/server/debug.ts | 3 ++- server/controllers/api/server/redundancy.ts | 6 +++--- server/controllers/api/users/index.ts | 4 ++-- server/controllers/api/users/me.ts | 6 +++--- server/controllers/api/users/token.ts | 7 ++++--- server/controllers/api/video-channel.ts | 4 ++-- server/controllers/api/videos/blacklist.ts | 6 +++--- server/controllers/api/videos/comment.ts | 5 ++++- server/controllers/api/videos/import.ts | 21 ++++++++++----------- server/controllers/api/videos/index.ts | 4 ++-- server/controllers/api/videos/live.ts | 2 +- server/controllers/api/videos/ownership.ts | 4 ++-- server/controllers/api/videos/upload.ts | 7 +++++-- 19 files changed, 74 insertions(+), 51 deletions(-) (limited to 'server/controllers/api') diff --git a/server/controllers/api/abuse.ts b/server/controllers/api/abuse.ts index 0ab74bdff..108627f81 100644 --- a/server/controllers/api/abuse.ts +++ b/server/controllers/api/abuse.ts @@ -142,7 +142,7 @@ async function updateAbuse (req: express.Request, res: express.Response) { // Do not send the delete to other instances, we updated OUR copy of this abuse - return res.sendStatus(HttpStatusCode.NO_CONTENT_204) + return res.status(HttpStatusCode.NO_CONTENT_204).end() } async function deleteAbuse (req: express.Request, res: express.Response) { @@ -154,7 +154,7 @@ async function deleteAbuse (req: express.Request, res: express.Response) { // Do not send the delete to other instances, we delete OUR copy of this abuse - return res.sendStatus(HttpStatusCode.NO_CONTENT_204) + return res.status(HttpStatusCode.NO_CONTENT_204).end() } async function reportAbuse (req: express.Request, res: express.Response) { @@ -244,5 +244,5 @@ async function deleteAbuseMessage (req: express.Request, res: express.Response) return abuseMessage.destroy({ transaction: t }) }) - return res.sendStatus(HttpStatusCode.NO_CONTENT_204) + return res.status(HttpStatusCode.NO_CONTENT_204).end() } diff --git a/server/controllers/api/bulk.ts b/server/controllers/api/bulk.ts index 649351029..192daccde 100644 --- a/server/controllers/api/bulk.ts +++ b/server/controllers/api/bulk.ts @@ -34,7 +34,7 @@ async function bulkRemoveCommentsOf (req: express.Request, res: express.Response const comments = await VideoCommentModel.listForBulkDelete(account, filter) // Don't wait result - res.sendStatus(HttpStatusCode.NO_CONTENT_204) + res.status(HttpStatusCode.NO_CONTENT_204).end() for (const comment of comments) { await removeComment(comment) diff --git a/server/controllers/api/custom-page.ts b/server/controllers/api/custom-page.ts index 3c47f7b9a..c19f03c56 100644 --- a/server/controllers/api/custom-page.ts +++ b/server/controllers/api/custom-page.ts @@ -27,7 +27,12 @@ export { async function getInstanceHomepage (req: express.Request, res: express.Response) { const page = await ActorCustomPageModel.loadInstanceHomepage() - if (!page) return res.sendStatus(HttpStatusCode.NOT_FOUND_404) + if (!page) { + return res.fail({ + status: HttpStatusCode.NOT_FOUND_404, + message: 'Instance homepage could not be found' + }) + } return res.json(page.toFormattedJSON()) } @@ -38,5 +43,5 @@ async function updateInstanceHomepage (req: express.Request, res: express.Respon await ActorCustomPageModel.updateInstanceHomepage(content) ServerConfigManager.Instance.updateHomepageState(content) - return res.sendStatus(HttpStatusCode.NO_CONTENT_204) + return res.status(HttpStatusCode.NO_CONTENT_204).end() } diff --git a/server/controllers/api/oauth-clients.ts b/server/controllers/api/oauth-clients.ts index c21e2298d..48a10d31f 100644 --- a/server/controllers/api/oauth-clients.ts +++ b/server/controllers/api/oauth-clients.ts @@ -24,7 +24,10 @@ async function getLocalClient (req: express.Request, res: express.Response, next // Don't make this check if this is a test instance if (process.env.NODE_ENV !== 'test' && req.get('host') !== headerHostShouldBe) { logger.info('Getting client tokens for host %s is forbidden (expected %s).', req.get('host'), headerHostShouldBe) - return res.type('json').status(HttpStatusCode.FORBIDDEN_403).end() + return res.fail({ + status: HttpStatusCode.FORBIDDEN_403, + message: `Getting client tokens for host ${req.get('host')} is forbidden` + }) } const client = await OAuthClientModel.loadFirstClient() diff --git a/server/controllers/api/plugins.ts b/server/controllers/api/plugins.ts index e18eed332..b64062287 100644 --- a/server/controllers/api/plugins.ts +++ b/server/controllers/api/plugins.ts @@ -144,7 +144,7 @@ async function installPlugin (req: express.Request, res: express.Response) { return res.json(plugin.toFormattedJSON()) } catch (err) { logger.warn('Cannot install plugin %s.', toInstall, { err }) - return res.sendStatus(HttpStatusCode.BAD_REQUEST_400) + return res.fail({ message: 'Cannot install plugin ' + toInstall }) } } @@ -159,7 +159,7 @@ async function updatePlugin (req: express.Request, res: express.Response) { return res.json(plugin.toFormattedJSON()) } catch (err) { logger.warn('Cannot update plugin %s.', toUpdate, { err }) - return res.sendStatus(HttpStatusCode.BAD_REQUEST_400) + return res.fail({ message: 'Cannot update plugin ' + toUpdate }) } } @@ -168,7 +168,7 @@ async function uninstallPlugin (req: express.Request, res: express.Response) { await PluginManager.Instance.uninstall(body.npmName) - return res.sendStatus(HttpStatusCode.NO_CONTENT_204) + return res.status(HttpStatusCode.NO_CONTENT_204).end() } function getPublicPluginSettings (req: express.Request, res: express.Response) { @@ -197,7 +197,7 @@ async function updatePluginSettings (req: express.Request, res: express.Response await PluginManager.Instance.onSettingsChanged(plugin.name, plugin.settings) - return res.sendStatus(HttpStatusCode.NO_CONTENT_204) + return res.status(HttpStatusCode.NO_CONTENT_204).end() } async function listAvailablePlugins (req: express.Request, res: express.Response) { @@ -206,8 +206,10 @@ async function listAvailablePlugins (req: express.Request, res: express.Response const resultList = await listAvailablePluginsFromIndex(query) if (!resultList) { - return res.status(HttpStatusCode.SERVICE_UNAVAILABLE_503) - .json({ error: 'Plugin index unavailable. Please retry later' }) + return res.fail({ + status: HttpStatusCode.SERVICE_UNAVAILABLE_503, + message: 'Plugin index unavailable. Please retry later' + }) } return res.json(resultList) diff --git a/server/controllers/api/search.ts b/server/controllers/api/search.ts index f0cdf3a89..77e3a024d 100644 --- a/server/controllers/api/search.ts +++ b/server/controllers/api/search.ts @@ -102,7 +102,10 @@ async function searchVideoChannelsIndex (query: VideoChannelsSearchQuery, res: e } catch (err) { logger.warn('Cannot use search index to make video channels search.', { err }) - return res.sendStatus(HttpStatusCode.INTERNAL_SERVER_ERROR_500) + return res.fail({ + status: HttpStatusCode.INTERNAL_SERVER_ERROR_500, + message: 'Cannot use search index to make video channels search' + }) } } @@ -202,7 +205,10 @@ async function searchVideosIndex (query: VideosSearchQuery, res: express.Respons } catch (err) { logger.warn('Cannot use search index to make video search.', { err }) - return res.sendStatus(HttpStatusCode.INTERNAL_SERVER_ERROR_500) + return res.fail({ + status: HttpStatusCode.INTERNAL_SERVER_ERROR_500, + message: 'Cannot use search index to make video search' + }) } } diff --git a/server/controllers/api/server/debug.ts b/server/controllers/api/server/debug.ts index ff0d9ca3c..a6e9147f3 100644 --- a/server/controllers/api/server/debug.ts +++ b/server/controllers/api/server/debug.ts @@ -1,5 +1,6 @@ import { InboxManager } from '@server/lib/activitypub/inbox-manager' import { RemoveDanglingResumableUploadsScheduler } from '@server/lib/schedulers/remove-dangling-resumable-uploads-scheduler' +import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' import { SendDebugCommand } from '@shared/models' import * as express from 'express' import { UserRight } from '../../../../shared/models/users' @@ -41,5 +42,5 @@ async function runCommand (req: express.Request, res: express.Response) { await RemoveDanglingResumableUploadsScheduler.Instance.execute() } - return res.sendStatus(204) + return res.status(HttpStatusCode.NO_CONTENT_204).end() } diff --git a/server/controllers/api/server/redundancy.ts b/server/controllers/api/server/redundancy.ts index 7c13dc21b..bc593ad43 100644 --- a/server/controllers/api/server/redundancy.ts +++ b/server/controllers/api/server/redundancy.ts @@ -90,13 +90,13 @@ async function addVideoRedundancy (req: express.Request, res: express.Response) payload }) - return res.sendStatus(HttpStatusCode.NO_CONTENT_204) + return res.status(HttpStatusCode.NO_CONTENT_204).end() } async function removeVideoRedundancyController (req: express.Request, res: express.Response) { await removeVideoRedundancy(res.locals.videoRedundancy) - return res.sendStatus(HttpStatusCode.NO_CONTENT_204) + return res.status(HttpStatusCode.NO_CONTENT_204).end() } async function updateRedundancy (req: express.Request, res: express.Response) { @@ -110,5 +110,5 @@ async function updateRedundancy (req: express.Request, res: express.Response) { removeRedundanciesOfServer(server.id) .catch(err => logger.error('Cannot remove redundancy of %s.', server.host, { err })) - return res.sendStatus(HttpStatusCode.NO_CONTENT_204) + return res.status(HttpStatusCode.NO_CONTENT_204).end() } diff --git a/server/controllers/api/users/index.ts b/server/controllers/api/users/index.ts index f384f0f28..d907b49bf 100644 --- a/server/controllers/api/users/index.ts +++ b/server/controllers/api/users/index.ts @@ -314,7 +314,7 @@ async function removeUser (req: express.Request, res: express.Response) { Hooks.runAction('action:api.user.deleted', { user }) - return res.sendStatus(HttpStatusCode.NO_CONTENT_204) + return res.status(HttpStatusCode.NO_CONTENT_204).end() } async function updateUser (req: express.Request, res: express.Response) { @@ -349,7 +349,7 @@ async function updateUser (req: express.Request, res: express.Response) { // Don't need to send this update to followers, these attributes are not federated - return res.sendStatus(HttpStatusCode.NO_CONTENT_204) + return res.status(HttpStatusCode.NO_CONTENT_204).end() } async function askResetUserPassword (req: express.Request, res: express.Response) { diff --git a/server/controllers/api/users/me.ts b/server/controllers/api/users/me.ts index a609abaa6..810e4295e 100644 --- a/server/controllers/api/users/me.ts +++ b/server/controllers/api/users/me.ts @@ -183,7 +183,7 @@ async function deleteMe (req: express.Request, res: express.Response) { await user.destroy() - return res.sendStatus(HttpStatusCode.NO_CONTENT_204) + return res.status(HttpStatusCode.NO_CONTENT_204).end() } async function updateMe (req: express.Request, res: express.Response) { @@ -237,7 +237,7 @@ async function updateMe (req: express.Request, res: express.Response) { await sendVerifyUserEmail(user, true) } - return res.sendStatus(HttpStatusCode.NO_CONTENT_204) + return res.status(HttpStatusCode.NO_CONTENT_204).end() } async function updateMyAvatar (req: express.Request, res: express.Response) { @@ -257,5 +257,5 @@ async function deleteMyAvatar (req: express.Request, res: express.Response) { const userAccount = await AccountModel.load(user.Account.id) await deleteLocalActorImageFile(userAccount, ActorImageType.AVATAR) - return res.sendStatus(HttpStatusCode.NO_CONTENT_204) + return res.status(HttpStatusCode.NO_CONTENT_204).end() } diff --git a/server/controllers/api/users/token.ts b/server/controllers/api/users/token.ts index 694bb0a92..863a3d74c 100644 --- a/server/controllers/api/users/token.ts +++ b/server/controllers/api/users/token.ts @@ -78,9 +78,10 @@ async function handleToken (req: express.Request, res: express.Response, next: e } catch (err) { logger.warn('Login error', { err }) - return res.status(err.code || 400).json({ - code: err.name, - error: err.message + return res.fail({ + status: err.code, + message: err.message, + type: err.name }) } } diff --git a/server/controllers/api/video-channel.ts b/server/controllers/api/video-channel.ts index 859d8b3c0..34207ea8a 100644 --- a/server/controllers/api/video-channel.ts +++ b/server/controllers/api/video-channel.ts @@ -180,7 +180,7 @@ async function deleteVideoChannelAvatar (req: express.Request, res: express.Resp await deleteLocalActorImageFile(videoChannel, ActorImageType.AVATAR) - return res.sendStatus(HttpStatusCode.NO_CONTENT_204) + return res.status(HttpStatusCode.NO_CONTENT_204).end() } async function deleteVideoChannelBanner (req: express.Request, res: express.Response) { @@ -188,7 +188,7 @@ async function deleteVideoChannelBanner (req: express.Request, res: express.Resp await deleteLocalActorImageFile(videoChannel, ActorImageType.BANNER) - return res.sendStatus(HttpStatusCode.NO_CONTENT_204) + return res.status(HttpStatusCode.NO_CONTENT_204).end() } async function addVideoChannel (req: express.Request, res: express.Response) { diff --git a/server/controllers/api/videos/blacklist.ts b/server/controllers/api/videos/blacklist.ts index fa8448c86..ca2b85ea5 100644 --- a/server/controllers/api/videos/blacklist.ts +++ b/server/controllers/api/videos/blacklist.ts @@ -70,7 +70,7 @@ async function addVideoToBlacklistController (req: express.Request, res: express logger.info('Video %s blacklisted.', videoInstance.uuid) - return res.type('json').sendStatus(HttpStatusCode.NO_CONTENT_204) + return res.type('json').status(HttpStatusCode.NO_CONTENT_204).end() } async function updateVideoBlacklistController (req: express.Request, res: express.Response) { @@ -82,7 +82,7 @@ async function updateVideoBlacklistController (req: express.Request, res: expres return videoBlacklist.save({ transaction: t }) }) - return res.type('json').sendStatus(HttpStatusCode.NO_CONTENT_204) + return res.type('json').status(HttpStatusCode.NO_CONTENT_204).end() } async function listBlacklist (req: express.Request, res: express.Response) { @@ -105,5 +105,5 @@ async function removeVideoFromBlacklistController (req: express.Request, res: ex logger.info('Video %s removed from blacklist.', video.uuid) - return res.type('json').sendStatus(HttpStatusCode.NO_CONTENT_204) + return res.type('json').status(HttpStatusCode.NO_CONTENT_204).end() } diff --git a/server/controllers/api/videos/comment.ts b/server/controllers/api/videos/comment.ts index cfdf2773f..e6f28c1cb 100644 --- a/server/controllers/api/videos/comment.ts +++ b/server/controllers/api/videos/comment.ts @@ -166,7 +166,10 @@ async function listVideoThreadComments (req: express.Request, res: express.Respo } if (resultList.data.length === 0) { - return res.sendStatus(HttpStatusCode.NOT_FOUND_404) + return res.fail({ + status: HttpStatusCode.NOT_FOUND_404, + message: 'No comments were found' + }) } return res.json(buildFormattedCommentTree(resultList)) diff --git a/server/controllers/api/videos/import.ts b/server/controllers/api/videos/import.ts index 0d5d7a962..6ee109a8f 100644 --- a/server/controllers/api/videos/import.ts +++ b/server/controllers/api/videos/import.ts @@ -18,7 +18,6 @@ import { } from '@server/types/models' import { MVideoImportFormattable } from '@server/types/models/video/video-import' import { ServerErrorCode, VideoImportCreate, VideoImportState, VideoPrivacy, VideoState } from '../../../../shared' -import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' import { ThumbnailType } from '../../../../shared/models/videos/thumbnail.type' import { auditLoggerFactory, getAuditIdFromRes, VideoImportAuditView } from '../../../helpers/audit-logger' import { moveAndProcessCaptionFile } from '../../../helpers/captions-utils' @@ -143,10 +142,12 @@ async function addYoutubeDLImport (req: express.Request, res: express.Response) } catch (err) { logger.info('Cannot fetch information from import for URL %s.', targetUrl, { err }) - return res.status(HttpStatusCode.BAD_REQUEST_400) - .json({ - error: 'Cannot fetch remote information of this URL.' - }) + return res.fail({ + message: 'Cannot fetch remote information of this URL.', + data: { + targetUrl + } + }) } const video = buildVideo(res.locals.videoChannel.id, body, youtubeDLInfo) @@ -333,12 +334,10 @@ async function processTorrentOrAbortRequest (req: express.Request, res: express. if (parsedTorrent.files.length !== 1) { cleanUpReqFiles(req) - res.status(HttpStatusCode.BAD_REQUEST_400) - .json({ - code: ServerErrorCode.INCORRECT_FILES_IN_TORRENT, - error: 'Torrents with only 1 file are supported.' - }) - + res.fail({ + type: ServerErrorCode.INCORRECT_FILES_IN_TORRENT.toString(), + message: 'Torrents with only 1 file are supported.' + }) return undefined } diff --git a/server/controllers/api/videos/index.ts b/server/controllers/api/videos/index.ts index 6483d2e8a..47ab098ef 100644 --- a/server/controllers/api/videos/index.ts +++ b/server/controllers/api/videos/index.ts @@ -146,7 +146,7 @@ async function viewVideo (req: express.Request, res: express.Response) { const exists = await Redis.Instance.doesVideoIPViewExist(ip, immutableVideoAttrs.uuid) if (exists) { logger.debug('View for ip %s and video %s already exists.', ip, immutableVideoAttrs.uuid) - return res.sendStatus(HttpStatusCode.NO_CONTENT_204) + return res.status(HttpStatusCode.NO_CONTENT_204).end() } const video = await VideoModel.load(immutableVideoAttrs.id) @@ -179,7 +179,7 @@ async function viewVideo (req: express.Request, res: express.Response) { Hooks.runAction('action:api.video.viewed', { video, ip }) - return res.sendStatus(HttpStatusCode.NO_CONTENT_204) + return res.status(HttpStatusCode.NO_CONTENT_204).end() } async function getVideoDescription (req: express.Request, res: express.Response) { diff --git a/server/controllers/api/videos/live.ts b/server/controllers/api/videos/live.ts index 04d2494ce..6b733c577 100644 --- a/server/controllers/api/videos/live.ts +++ b/server/controllers/api/videos/live.ts @@ -76,7 +76,7 @@ async function updateLiveVideo (req: express.Request, res: express.Response) { await federateVideoIfNeeded(video, false) - return res.sendStatus(HttpStatusCode.NO_CONTENT_204) + return res.status(HttpStatusCode.NO_CONTENT_204).end() } async function addLiveVideo (req: express.Request, res: express.Response) { diff --git a/server/controllers/api/videos/ownership.ts b/server/controllers/api/videos/ownership.ts index 6102f28dc..2d6ca60a8 100644 --- a/server/controllers/api/videos/ownership.ts +++ b/server/controllers/api/videos/ownership.ts @@ -122,7 +122,7 @@ function acceptOwnership (req: express.Request, res: express.Response) { videoChangeOwnership.status = VideoChangeOwnershipStatus.ACCEPTED await videoChangeOwnership.save({ transaction: t }) - return res.sendStatus(HttpStatusCode.NO_CONTENT_204) + return res.status(HttpStatusCode.NO_CONTENT_204).end() }) } @@ -133,6 +133,6 @@ function refuseOwnership (req: express.Request, res: express.Response) { videoChangeOwnership.status = VideoChangeOwnershipStatus.REFUSED await videoChangeOwnership.save({ transaction: t }) - return res.sendStatus(HttpStatusCode.NO_CONTENT_204) + return res.status(HttpStatusCode.NO_CONTENT_204).end() }) } diff --git a/server/controllers/api/videos/upload.ts b/server/controllers/api/videos/upload.ts index ebc17c760..c33d7fcb9 100644 --- a/server/controllers/api/videos/upload.ts +++ b/server/controllers/api/videos/upload.ts @@ -97,8 +97,11 @@ export async function addVideoLegacy (req: express.Request, res: express.Respons // Uploading the video could be long // Set timeout to 10 minutes, as Express's default is 2 minutes req.setTimeout(1000 * 60 * 10, () => { - logger.error('Upload video has timed out.') - return res.sendStatus(HttpStatusCode.REQUEST_TIMEOUT_408) + logger.error('Video upload has timed out.') + return res.fail({ + status: HttpStatusCode.REQUEST_TIMEOUT_408, + message: 'Video upload has timed out.' + }) }) const videoPhysicalFile = req.files['videofile'][0] -- cgit v1.2.3