diff --git a/public/src/modules/api.js b/public/src/modules/api.js index 55abd1ad36..7c1038fbde 100644 --- a/public/src/modules/api.js +++ b/public/src/modules/api.js @@ -79,7 +79,11 @@ async function xhr(options) { if (!res.ok) { if (response) { - throw new Error(isJSON ? response.status.message : response); + const jsonError = isJSON && (response.status?.message || response.error || ''); + throw new Error(isJSON && jsonError ? + jsonError : + response + ); } throw new Error(res.statusText); } diff --git a/src/categories/create.js b/src/categories/create.js index 92f63f27e6..fa49468834 100644 --- a/src/categories/create.js +++ b/src/categories/create.js @@ -101,7 +101,7 @@ module.exports = function (Categories) { await privileges.categories.give(result.guestPrivileges, category.cid, ['guests', 'spiders']); cache.del('categories:cid'); - await clearParentCategoryCache(parentCid); + await Categories.clearParentCategoryCache(parentCid); if (data.cloneFromCid && parseInt(data.cloneFromCid, 10)) { category = await Categories.copySettingsFrom(data.cloneFromCid, category.cid, !data.parentCid); @@ -115,8 +115,8 @@ module.exports = function (Categories) { return category; }; - async function clearParentCategoryCache(parentCid) { - while (parseInt(parentCid, 10) >= 0) { + Categories.clearParentCategoryCache = async function (parentCid) { + while (parentCid || parseInt(parentCid, 10) === 0) { cache.del([ `cid:${parentCid}:children`, `cid:${parentCid}:children:all`, @@ -129,7 +129,7 @@ module.exports = function (Categories) { // eslint-disable-next-line no-await-in-loop parentCid = await Categories.getCategoryField(parentCid, 'parentCid'); } - } + }; async function duplicateCategoriesChildren(parentCid, cid, uid) { let children = await Categories.getChildren([cid], uid); @@ -188,17 +188,13 @@ module.exports = function (Categories) { throw new Error('[[error:invalid-cid]]'); } - const oldParent = parseInt(destination.parentCid, 10) || 0; - const newParent = parseInt(source.parentCid, 10) || 0; - if (copyParent && newParent !== parseInt(toCid, 10)) { + const oldParent = String(destination.parentCid || 0); + const newParent = String(source.parentCid || 0); + if (copyParent && newParent !== String(toCid)) { await db.sortedSetRemove(`cid:${oldParent}:children`, toCid); await db.sortedSetAdd(`cid:${newParent}:children`, source.order, toCid); - cache.del([ - `cid:${oldParent}:children`, - `cid:${oldParent}:children:all`, - `cid:${newParent}:children`, - `cid:${newParent}:children:all`, - ]); + await Categories.clearParentCategoryCache(oldParent); + await Categories.clearParentCategoryCache(newParent); } destination.description = source.description; diff --git a/src/categories/delete.js b/src/categories/delete.js index 3074cf3f55..5f96e32676 100644 --- a/src/categories/delete.js +++ b/src/categories/delete.js @@ -79,12 +79,13 @@ module.exports = function (Categories) { cache.del([ 'categories:cid', 'cid:0:children', - `cid:${parentCid}:children`, - `cid:${parentCid}:children:all`, - `cid:${cid}:children`, - `cid:${cid}:children:all`, + 'cid:0:children:all', `cid:${cid}:tag:whitelist`, ]); + await Promise.all([ + Categories.clearParentCategoryCache(parentCid), + Categories.clearParentCategoryCache(cid), + ]); } async function deleteTags(cid) { diff --git a/src/categories/update.js b/src/categories/update.js index ff4d6e4d11..0579019e2f 100644 --- a/src/categories/update.js +++ b/src/categories/update.js @@ -85,12 +85,9 @@ module.exports = function (Categories) { db.sortedSetAdd(`cid:${newParent}:children`, categoryData.order, cid), db.setObjectField(`${utils.isNumber(cid) ? 'category' : 'categoryRemote'}:${cid}`, 'parentCid', newParent), ]); - - cache.del([ - `cid:${oldParent}:children`, - `cid:${newParent}:children`, - `cid:${oldParent}:children:all`, - `cid:${newParent}:children:all`, + await Promise.all([ + Categories.clearParentCategoryCache(oldParent), + Categories.clearParentCategoryCache(newParent), ]); } @@ -134,11 +131,9 @@ module.exports = function (Categories) { await db.setObjectBulk( childrenCids.map((cid, index) => [`${utils.isNumber(cid) ? 'category' : 'categoryRemote'}:${cid}`, { order: index + 1 }]) ); - + await Categories.clearParentCategoryCache(parentCid); cache.del([ 'categories:cid', - `cid:${parentCid}:children`, - `cid:${parentCid}:children:all`, ]); } diff --git a/src/controllers/admin/categories.js b/src/controllers/admin/categories.js index 5e503b1964..54c9b276f6 100644 --- a/src/controllers/admin/categories.js +++ b/src/controllers/admin/categories.js @@ -202,13 +202,14 @@ categoriesController.addRemote = async function (req, res) { return res.sendStatus(404); } - const score = await db.sortedSetCard('cid:0:children'); - const order = score + 1; // order is 1-based lol + const lastItem = await db.getSortedSetRevRangeWithScores('cid:0:children', 0, 0); + const order = lastItem.length ? lastItem[0].score + 1 : 1; await Promise.all([ db.sortedSetAdd('cid:0:children', order, id), categories.setCategoryField(id, 'order', order), ]); cache.del('cid:0:children'); + cache.del('cid:0:children:all'); res.sendStatus(200); }; @@ -231,7 +232,7 @@ categoriesController.removeRemote = async function (req, res) { const parentCid = await categories.getCategoryField(req.params.cid, 'parentCid'); await db.sortedSetRemove(`cid:${parentCid || 0}:children`, req.params.cid); - cache.del(`cid:${parentCid || 0}:children`); - + await categories.clearParentCategoryCache(parentCid || 0); + await categories.setCategoryField(req.params.cid, 'parentCid', 0); res.sendStatus(200); };