-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Convert project.controller
to async
/await
syntax
#3025
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Convert project.controller
to async
/await
syntax
#3025
Conversation
// save project to some path | ||
buildZip(project, req, res); | ||
}); | ||
export async function downloadProjectAsZip(req, res) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
downloadProjectAsZip
, if the project with the given ID doesn't exist, the function sends a response with a 404 status code but doesn't return or terminate the function. We can consider using return
or else
to prevent further execution if the project doesn't exist.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right. Good catch!
I have reviewed the file and I have few suggestions:
|
Thank you for the detailed and thoughtful review! This helps a lot more than a "LGTM". Most of the things that you are mentioning are in existing code that I didn't change. There's always a balance between changing too much at once and wanting to fix everything. If I'm trying not to change too much usually it's because I don't want to overwhelm the reviewer. But since you're here and you're looking at this then let's do it!
I'm not sure if we want to send specific mongodb errors back in API responses. In a normal web app that could be a security concern so I would send a somewhat vague error back to the user but log a specific error for developers to review. Since we're open source the security is probably not an issue since anyone can already see out database structure. I'm also not sure what sort of persistent logging capabilities we have. Only @raclim has access to the production environment. There was a recent PR #2814 which sets up Winston, which honestly I'm not too familiar with. At my work we use Sentry which is a third-party web app. The 400 Bad Request is probably not the best error code. I think the ones we want are 500 Internal Server when there's an unexpected database error and 404 Not Found (or possibly 422 Unprocessable Entity) if the project doesn't exist. We can check for a 404 up on line 24 when we query for the project. It seems weird that we use
Good thoughts but not needed due to 4.
Feel free to raise a PR with a specific improvement that you have in mind.
Yes! I noticed this and I was going to change it and then I decided to keep it as-is so that I wasn't changing too much. But that's dumb as this really should be changed. Will fix.
This topic came up in an issue that I worked on recently where you couldn't download a sketch if it contained deleted files. I wasn't sure the best way to handle it. I settled on returning a 0kb file. I think that we do want to download what we can, rather than aborting the entire download, but I agree that it would be nice if there was some way to warn the user that their download contains missing files. See PR #2315 issue #2314.
This is definitely a concern of mine! @mhsh312 has been working on downloading entire collections (#2735 and #2707) and I am worried that it might be too much data. Maybe you can work on this? It's issue #643. |
Thanks for your review. I would love to work on this. I am a student from India, and currently my university exams are going on. I would start to work on this by 23rd Jan, if we are not in sprint. When I had reviewed it, almost all the implementations are in my mind. I will raise the PR on this branch. Then you can merge my PR with this PR, and this PR will be ready. |
I got some free time, I thought I should find the solutions,
It's a valid observation. Indeed, it seems redundant to perform a separate Here's how we can refactor the export async function updateProject(req, res) {
try {
const project = await Project.findById(req.params.project_id).exec();
if (!project) {
res.status(404).send({
success: false,
message: 'Project with that id does not exist.'
});
return;
}
if (!project.user.equals(req.user._id)) {
res.status(403).send({
success: false,
message: 'Session does not match owner of project.'
});
return;
}
if (
req.body.updatedAt &&
isAfter(new Date(project.updatedAt), new Date(req.body.updatedAt))
) {
res.status(409).send({
success: false,
message: 'Attempted to save stale version of project.'
});
return;
}
// Update the project directly without another database query
Object.assign(project, req.body);
const updatedProject = await project.save();
res.json(updatedProject);
} catch (error) {
console.error(error);
res.status(500).json({ success: false });
}
} By updating the project object retrieved from the database and then saving it, we avoid the need for an additional database query. This consolidation streamlines the code and improves performance by reducing database interactions.
Okey, I will raise the PR.
Handling errors when fetching a file's content via Axios in the Here's how we can enhance the error handling in the /**
* Recursively adds a file and all of its children to the JSZip instance.
* @param {object} file
* @param {Array<object>} files
* @param {JSZip} zip
* @return {Promise<void>} - modifies the `zip` parameter
*/
async function addFileToZip(file, files, zip) {
if (file.fileType === 'folder') {
const folderZip = file.name === 'root' ? zip : zip.folder(file.name);
await Promise.all(
file.children.map((fileId) => {
const childFile = files.find((f) => f.id === fileId);
return addFileToZip(childFile, files, folderZip);
})
);
} else if (file.url) {
try {
const res = await axios.get(file.url, {
responseType: 'arraybuffer'
});
zip.file(file.name, res.data);
} catch (error) {
console.error(`Error fetching file '${file.name}' from '${file.url}':`, error);
// Provide a fallback mechanism or notify the user about the error
// For example, we can create an empty file or log the error and proceed
zip.file(file.name, new ArrayBuffer(0)); // Create an empty file
}
} else {
zip.file(file.name, file.content);
}
} In this updated version of the function, we catch errors that occur during the file fetch operation using Axios. If an error occurs, we log the error to the console for debugging purposes, and then we provide a fallback mechanism by creating an empty file in the zip archive. This ensures that the file download process continues even if some files cannot be fetched successfully. We can customize the fallback mechanism based on your specific requirements and user experience considerations. Providing feedback to users about any missing or inaccessible files is important for transparency and user satisfaction.
Cool. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your work @lindapaiste and @Swarnendu0123 on this! I'm going to merge this in!
Also thanks for sharing the tidbit about the Whitespace! I've been trying to figure out how to change the appearance and never really figured it out 😂
Ref #521
Ref #3024
Changes:
project.controller.js
file to useasync
/await
syntax.innerErr
"callback hell" and flatten the structure.Promise
wrapping ingetProjectsForUserId
.Improvements:
Often when a refactor a part of the code I find things that are not right. Here are some specific problems that I fixed:
Return a 404 error on
getProject
when the project is not found. (Incorrect 404 error handling for mongoosefindOne
#3024)p5.js-web-editor/server/controllers/project.controller.js
Lines 99 to 107 in 6cac275
https://github.com/lindapaiste/p5.js-web-editor/blob/07a4b6ea76e7eac94f9e435d22279912952d4e4c/server/controllers/project.controller.js#L87-L91
Make the
Promise
returned bygetProjectsForUserId
reject on error instead of resolving, allowing errors to bubble up and be caught by Express middleware.p5.js-web-editor/server/controllers/project.controller.js
Lines 116 to 121 in 6cac275
https://github.com/lindapaiste/p5.js-web-editor/blob/07a4b6ea76e7eac94f9e435d22279912952d4e4c/server/controllers/project.controller.js#L96-L99
Add error handling to
downloadProjectAsZip
. The current code would crash with aTypeError
if there was no project.p5.js-web-editor/server/controllers/project.controller.js
Lines 267 to 272 in 6cac275
https://github.com/lindapaiste/p5.js-web-editor/blob/07a4b6ea76e7eac94f9e435d22279912952d4e4c/server/controllers/project.controller.js#L239-L246
I have verified that this pull request:
npm run lint
)npm run test
)develop
branch.Fixes #123
@raclim It is much easier to review the changes with the "Ignore whitespace" option. I finally figured out how to do that on GitHub!
