1
0
Fork 0
mirror of https://github.com/plankanban/planka.git synced 2025-08-09 15:35:29 +02:00

#27 better error handling and restructuring

This commit is contained in:
Christoph Enne 2022-12-10 18:03:08 +01:00
parent 7596f5348c
commit 3270a0338e
3 changed files with 62 additions and 43 deletions

View file

@ -5,6 +5,9 @@ const Errors = {
PROJECT_NOT_FOUND: { PROJECT_NOT_FOUND: {
projectNotFound: 'Project not found', projectNotFound: 'Project not found',
}, },
TRELLO_FILE_INVALID: {
trelloFileInvalid: 'Trello File invalid',
},
}; };
module.exports = { module.exports = {
@ -28,42 +31,44 @@ module.exports = {
projectNotFound: { projectNotFound: {
responseType: 'notFound', responseType: 'notFound',
}, },
trelloFileInvalid: {
responseType: 'badRequest',
},
}, },
async fn(inputs) { async fn(inputs) {
const { currentUser } = this.req; const { currentUser } = this.req;
const project = await Project.findOne(inputs.projectId);
if (!project) {
throw Errors.PROJECT_NOT_FOUND;
}
const isProjectManager = await sails.helpers.users.isProjectManager(currentUser.id, project.id);
if (!isProjectManager) {
throw Errors.PROJECT_NOT_FOUND;
}
const upload = util.promisify((options, callback) => const upload = util.promisify((options, callback) =>
this.req.file('file').upload(options, (error, files) => callback(error, files)), this.req.file('file').upload(options, (error, files) => callback(error, files)),
); );
let files; let files;
let trelloBoard;
try { try {
files = await upload({ files = await upload({
saveAs: uuid(), saveAs: uuid(),
maxBytes: null, maxBytes: null,
}); });
trelloBoard = await sails.helpers.boards.loadTrelloFile(files[0]);
} catch (error) { } catch (error) {
return exits.uploadError(error.message); // TODO: add error throw Errors.TRELLO_FILE_INVALID;
}
const project = await Project.findOne(inputs.projectId);
if (!project) {
throw Errors.PROJECT_NOT_FOUND;
}
const isProjectManager = await sails.helpers.users.isProjectManager(currentUser.id, project.id);
if (!isProjectManager) {
throw Errors.PROJECT_NOT_FOUND; // Forbidden
} }
const values = { const values = {
..._.pick(inputs, ['position', 'name']), ..._.pick(inputs, ['position', 'name']),
type: 'kanban', type: 'kanban',
}; };
const { board, boardMembership } = await sails.helpers.boards.createOne( const { board, boardMembership } = await sails.helpers.boards.createOne(
values, values,
currentUser, currentUser,
@ -71,10 +76,10 @@ module.exports = {
this.req, this.req,
); );
await sails.helpers.boards.importTrello(currentUser, board, files[0], this.req); await sails.helpers.boards.importTrello(currentUser, board, trelloBoard, this.req);
if (this.req.isSocket) { if (this.req.isSocket) {
sails.sockets.join(this.req, `board:${board.id}`); // TODO: only when subscription needed sails.sockets.join(this.req, `board:${board.id}`);
} }
return { return {

View file

@ -1,18 +1,14 @@
const fs = require('fs');
async function importFromTrello(inputs) { async function importFromTrello(inputs) {
let trelloBoard; const getTrelloLists = () => inputs.trelloBoard.lists.filter((list) => !list.closed);
const getTrelloLists = () => trelloBoard.lists.filter((list) => !list.closed);
const getTrelloCardsOfList = (listId) => const getTrelloCardsOfList = (listId) =>
trelloBoard.cards.filter((l) => l.idList === listId && !l.closed); inputs.trelloBoard.cards.filter((l) => l.idList === listId && !l.closed);
const getAllTrelloCheckItemsOfCard = (cardId) => const getAllTrelloCheckItemsOfCard = (cardId) =>
trelloBoard.checklists inputs.trelloBoard.checklists
.filter((c) => c.idCard === cardId) .filter((c) => c.idCard === cardId)
.map((checklist) => checklist.checkItems) .map((checklist) => checklist.checkItems)
.flat(); .flat();
const getTrelloCommentsOfCard = (cardId) => const getTrelloCommentsOfCard = (cardId) =>
trelloBoard.actions.filter( inputs.trelloBoard.actions.filter(
(action) => (action) =>
action.type === 'commentCard' && action.type === 'commentCard' &&
action.data && action.data &&
@ -20,19 +16,6 @@ async function importFromTrello(inputs) {
action.data.card.id === cardId, action.data.card.id === cardId,
); );
const loadTrelloFile = async () =>
new Promise((resolve, reject) => {
fs.readFile(inputs.file.fd, (err, data) => {
const exp = data && JSON.parse(data);
if (err) {
reject(err);
return;
}
trelloBoard = exp;
resolve(exp);
});
});
const importComments = async (trelloCard, plankaCard) => { const importComments = async (trelloCard, plankaCard) => {
const trelloComments = getTrelloCommentsOfCard(trelloCard.id); const trelloComments = getTrelloCommentsOfCard(trelloCard.id);
trelloComments.sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()); trelloComments.sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime());
@ -112,7 +95,6 @@ async function importFromTrello(inputs) {
); );
}; };
await loadTrelloFile();
await importLists(); await importLists();
} }
@ -126,7 +108,7 @@ module.exports = {
type: 'ref', type: 'ref',
required: true, required: true,
}, },
file: { trelloBoard: {
type: 'json', type: 'json',
required: true, required: true,
}, },
@ -136,12 +118,8 @@ module.exports = {
}, },
async fn(inputs) { async fn(inputs) {
// TODO some validations or something? check if the input file is ok?
await importFromTrello(inputs); await importFromTrello(inputs);
// TODO handle errors properly
return { return {
board: inputs.board, board: inputs.board,
}; };

View file

@ -0,0 +1,36 @@
const fs = require('fs');
module.exports = {
inputs: {
file: {
type: 'json',
required: true,
},
},
async fn(inputs) {
const isValidTrelloFile = (content) =>
content &&
Array.isArray(content.lists) &&
Array.isArray(content.cards) &&
Array.isArray(content.checklists) &&
Array.isArray(content.actions);
return new Promise((resolve, reject) => {
fs.readFile(inputs.file.fd, (err, data) => {
try {
const exp = data && JSON.parse(data);
if (err) {
reject(err);
} else if (isValidTrelloFile(exp)) {
resolve(exp);
} else {
reject(new Error('Invalid Trello File'));
}
} catch (e) {
reject(new Error(e));
}
});
});
},
};