mirror of
https://github.com/BobbyWibowo/lolisafe.git
synced 2024-12-14 08:26:22 +00:00
refactor: init UserError, a custom Error object
This will be used for errors that are to be delivered to users, AND not to be logged into the server (as in it stacktraces and all). This will eventually remove the need to throw string literals. In this commit, this has only been implemented on albumsController.js, but more will soon to come.
This commit is contained in:
parent
0dfdccb25e
commit
ae31033c0c
@ -7,6 +7,8 @@ const paths = require('./pathsController')
|
|||||||
const perms = require('./permissionController')
|
const perms = require('./permissionController')
|
||||||
const uploadController = require('./uploadController')
|
const uploadController = require('./uploadController')
|
||||||
const utils = require('./utilsController')
|
const utils = require('./utilsController')
|
||||||
|
const apiErrorsHandler = require('./handlers/apiErrorsHandler.js')
|
||||||
|
const UserError = require('./utils/UserError')
|
||||||
const config = require('./../config')
|
const config = require('./../config')
|
||||||
const logger = require('./../logger')
|
const logger = require('./../logger')
|
||||||
const db = require('knex')(config.database)
|
const db = require('knex')(config.database)
|
||||||
@ -66,10 +68,11 @@ self.getUniqueRandomName = async () => {
|
|||||||
return identifier
|
return identifier
|
||||||
}
|
}
|
||||||
|
|
||||||
throw 'Sorry, we could not allocate a unique random identifier. Try again?'
|
throw new UserError('Failed to allocate a unique identifier for the album. Try again?', 500)
|
||||||
}
|
}
|
||||||
|
|
||||||
self.list = async (req, res, next) => {
|
self.list = async (req, res, next) => {
|
||||||
|
try {
|
||||||
const user = await utils.authorize(req, res)
|
const user = await utils.authorize(req, res)
|
||||||
if (!user) return
|
if (!user) return
|
||||||
|
|
||||||
@ -87,7 +90,6 @@ self.list = async (req, res, next) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
// Query albums count for pagination
|
// Query albums count for pagination
|
||||||
const count = await db.table('albums')
|
const count = await db.table('albums')
|
||||||
.where(filter)
|
.where(filter)
|
||||||
@ -164,12 +166,12 @@ self.list = async (req, res, next) => {
|
|||||||
|
|
||||||
return res.json({ success: true, albums, count, users, homeDomain })
|
return res.json({ success: true, albums, count, users, homeDomain })
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(error)
|
return apiErrorsHandler(error, req, res, next)
|
||||||
return res.status(500).json({ success: false, description: 'An unexpected error occurred. Try again?' })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.create = async (req, res, next) => {
|
self.create = async (req, res, next) => {
|
||||||
|
try {
|
||||||
const user = await utils.authorize(req, res)
|
const user = await utils.authorize(req, res)
|
||||||
if (!user) return
|
if (!user) return
|
||||||
|
|
||||||
@ -179,7 +181,6 @@ self.create = async (req, res, next) => {
|
|||||||
|
|
||||||
if (!name) return res.json({ success: false, description: 'No album name specified.' })
|
if (!name) return res.json({ success: false, description: 'No album name specified.' })
|
||||||
|
|
||||||
try {
|
|
||||||
const album = await db.table('albums')
|
const album = await db.table('albums')
|
||||||
.where({
|
.where({
|
||||||
name,
|
name,
|
||||||
@ -211,8 +212,7 @@ self.create = async (req, res, next) => {
|
|||||||
|
|
||||||
return res.json({ success: true, id: ids[0] })
|
return res.json({ success: true, id: ids[0] })
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(error)
|
return apiErrorsHandler(error, req, res, next)
|
||||||
return res.status(500).json({ success: false, description: 'An unexpected error occurred. Try again?' })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,6 +222,7 @@ self.delete = async (req, res, next) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.disable = async (req, res, next) => {
|
self.disable = async (req, res, next) => {
|
||||||
|
try {
|
||||||
const user = await utils.authorize(req, res)
|
const user = await utils.authorize(req, res)
|
||||||
if (!user) return
|
if (!user) return
|
||||||
|
|
||||||
@ -229,7 +230,6 @@ self.disable = async (req, res, next) => {
|
|||||||
const purge = req.body.purge
|
const purge = req.body.purge
|
||||||
if (!Number.isFinite(id)) return res.json({ success: false, description: 'No album specified.' })
|
if (!Number.isFinite(id)) return res.json({ success: false, description: 'No album specified.' })
|
||||||
|
|
||||||
try {
|
|
||||||
if (purge) {
|
if (purge) {
|
||||||
const files = await db.table('files')
|
const files = await db.table('files')
|
||||||
.where({
|
.where({
|
||||||
@ -264,17 +264,14 @@ self.disable = async (req, res, next) => {
|
|||||||
.then(row => row.identifier)
|
.then(row => row.identifier)
|
||||||
|
|
||||||
await paths.unlink(path.join(paths.zips, `${identifier}.zip`))
|
await paths.unlink(path.join(paths.zips, `${identifier}.zip`))
|
||||||
} catch (error) {
|
|
||||||
if (error && error.code !== 'ENOENT') {
|
|
||||||
logger.error(error)
|
|
||||||
return res.status(500).json({ success: false, description: 'An unexpected error occurred. Try again?' })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return res.json({ success: true })
|
return res.json({ success: true })
|
||||||
|
} catch (error) {
|
||||||
|
return apiErrorsHandler(error, req, res, next)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.edit = async (req, res, next) => {
|
self.edit = async (req, res, next) => {
|
||||||
|
try {
|
||||||
const user = await utils.authorize(req, res)
|
const user = await utils.authorize(req, res)
|
||||||
if (!user) return
|
if (!user) return
|
||||||
|
|
||||||
@ -300,7 +297,6 @@ self.edit = async (req, res, next) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
const album = await db.table('albums')
|
const album = await db.table('albums')
|
||||||
.where(filter)
|
.where(filter)
|
||||||
.first()
|
.first()
|
||||||
@ -358,8 +354,7 @@ self.edit = async (req, res, next) => {
|
|||||||
return res.json({ success: true, name })
|
return res.json({ success: true, name })
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(error)
|
return apiErrorsHandler(error, req, res, next)
|
||||||
return res.status(500).json({ success: false, description: 'An unexpected error occurred. Try again?' })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -370,12 +365,12 @@ self.rename = async (req, res, next) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.get = async (req, res, next) => {
|
self.get = async (req, res, next) => {
|
||||||
|
try {
|
||||||
const identifier = req.params.identifier
|
const identifier = req.params.identifier
|
||||||
if (identifier === undefined) {
|
if (identifier === undefined) {
|
||||||
return res.status(401).json({ success: false, description: 'No identifier provided.' })
|
return res.status(401).json({ success: false, description: 'No identifier provided.' })
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
const album = await db.table('albums')
|
const album = await db.table('albums')
|
||||||
.where({
|
.where({
|
||||||
identifier,
|
identifier,
|
||||||
@ -416,12 +411,12 @@ self.get = async (req, res, next) => {
|
|||||||
files
|
files
|
||||||
})
|
})
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(error)
|
return apiErrorsHandler(error, req, res, next)
|
||||||
return res.status(500).json({ success: false, description: 'An unexpected error occcured. Try again?' })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.generateZip = async (req, res, next) => {
|
self.generateZip = async (req, res, next) => {
|
||||||
|
try {
|
||||||
const versionString = parseInt(req.query.v)
|
const versionString = parseInt(req.query.v)
|
||||||
|
|
||||||
const identifier = req.params.identifier
|
const identifier = req.params.identifier
|
||||||
@ -439,7 +434,6 @@ self.generateZip = async (req, res, next) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
const album = await db.table('albums')
|
const album = await db.table('albums')
|
||||||
.where({
|
.where({
|
||||||
identifier,
|
identifier,
|
||||||
@ -547,8 +541,7 @@ self.generateZip = async (req, res, next) => {
|
|||||||
self.zipEmitters.get(identifier).emit('done', filePath, fileName)
|
self.zipEmitters.get(identifier).emit('done', filePath, fileName)
|
||||||
return res.download(filePath, fileName)
|
return res.download(filePath, fileName)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(error)
|
return apiErrorsHandler(error, req, res, next)
|
||||||
return res.status(500).json({ success: false, description: 'An unexpected error occurred. Try again?' })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -589,20 +582,21 @@ self.listFiles = async (req, res, next) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.addFiles = async (req, res, next) => {
|
self.addFiles = async (req, res, next) => {
|
||||||
|
let ids, albumid, failed, albumids
|
||||||
|
try {
|
||||||
const user = await utils.authorize(req, res)
|
const user = await utils.authorize(req, res)
|
||||||
if (!user) return
|
if (!user) return
|
||||||
|
|
||||||
const ids = req.body.ids
|
ids = req.body.ids
|
||||||
if (!Array.isArray(ids) || !ids.length) {
|
if (!Array.isArray(ids) || !ids.length) {
|
||||||
return res.json({ success: false, description: 'No files specified.' })
|
return res.json({ success: false, description: 'No files specified.' })
|
||||||
}
|
}
|
||||||
|
|
||||||
let albumid = parseInt(req.body.albumid)
|
albumid = parseInt(req.body.albumid)
|
||||||
if (isNaN(albumid) || albumid < 0) albumid = null
|
if (isNaN(albumid) || albumid < 0) albumid = null
|
||||||
|
|
||||||
let failed = []
|
failed = []
|
||||||
const albumids = []
|
albumids = []
|
||||||
try {
|
|
||||||
if (albumid !== null) {
|
if (albumid !== null) {
|
||||||
const album = await db.table('albums')
|
const album = await db.table('albums')
|
||||||
.where('id', albumid)
|
.where('id', albumid)
|
||||||
@ -646,14 +640,13 @@ self.addFiles = async (req, res, next) => {
|
|||||||
|
|
||||||
return res.json({ success: true, failed })
|
return res.json({ success: true, failed })
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(error)
|
if (Array.isArray(failed) && (failed.length === ids.length)) {
|
||||||
if (failed.length === ids.length) {
|
|
||||||
return res.json({
|
return res.json({
|
||||||
success: false,
|
success: false,
|
||||||
description: `Could not ${albumid === null ? 'add' : 'remove'} any files ${albumid === null ? 'to' : 'from'} the album.`
|
description: `Could not ${albumid === null ? 'add' : 'remove'} any files ${albumid === null ? 'to' : 'from'} the album.`
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
return res.status(500).json({ success: false, description: 'An unexpected error occurred. Try again?' })
|
return apiErrorsHandler(error, req, res, next)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
30
controllers/handlers/apiErrorsHandler.js
Normal file
30
controllers/handlers/apiErrorsHandler.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
const UserError = require('./../utils/UserError')
|
||||||
|
const logger = require('./../../logger')
|
||||||
|
|
||||||
|
module.exports = (error, req, res, next) => {
|
||||||
|
if (!res) {
|
||||||
|
return logger.error(new Error('Missing "res" object.'))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Intentional error messages to be delivered to users
|
||||||
|
const isUserError = error instanceof UserError
|
||||||
|
|
||||||
|
// ENOENT or missing file errors, typically harmless, so do not log stacktrace
|
||||||
|
const isENOENTError = error instanceof Error && error.code === 'ENOENT'
|
||||||
|
|
||||||
|
if (!isUserError && !isENOENTError) {
|
||||||
|
logger.error(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
const statusCode = isUserError
|
||||||
|
? error.statusCode
|
||||||
|
: 500
|
||||||
|
|
||||||
|
const description = isUserError
|
||||||
|
? error.message
|
||||||
|
: 'An unexpected error occurred. Try again?'
|
||||||
|
|
||||||
|
return res
|
||||||
|
.status(statusCode)
|
||||||
|
.json({ success: false, description })
|
||||||
|
}
|
11
controllers/utils/UserError.js
Normal file
11
controllers/utils/UserError.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
class UserError extends Error {
|
||||||
|
constructor (message, statusCode) {
|
||||||
|
super(message)
|
||||||
|
|
||||||
|
this.statusCode = statusCode !== undefined
|
||||||
|
? statusCode
|
||||||
|
: 400
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = UserError
|
Loading…
Reference in New Issue
Block a user