Skip to content

task solution#324

Open
IvanRyabukha wants to merge 3 commits intomate-academy:masterfrom
IvanRyabukha:develop
Open

task solution#324
IvanRyabukha wants to merge 3 commits intomate-academy:masterfrom
IvanRyabukha:develop

Conversation

@IvanRyabukha
Copy link

No description provided.

Copy link

@mateacademy-ai-mentor mateacademy-ai-mentor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

Good start on this file moving utility! You've correctly handled the command-line arguments and basic path logic. However, I'm requesting changes because the current implementation deviates from several core technical requirements.

The most critical issue is that the move operation must be implemented by copying the file with streams (fs.createReadStream piped to fs.createWriteStream) and then deleting the source file (fs.promises.unlink). Your solution uses fs.renameSync, which does not meet this specific requirement.

Additionally, the task requires using asynchronous, promise-based methods like fs.promises.stat() to avoid blocking operations. Your code should be refactored into an async function that uses await instead of synchronous functions like fs.statSync.

Finally, please update the error handling to throw new Error(...) for all failure cases instead of logging to console.error, as specified in the requirements.


✨ Please rate this review in the Platform's notification center1. I will be grateful for your feedback! ✨

Important

Fix the issues, commit the changes, and then re-request my review using the Re-request review button2 in the Reviewers tab.

Tip

If you have any comments about this review, please leave a message in the Add a comment section below and mention me with the @mateacademy-ai-mentor tag3.
I will read your message during my next review of your pull request. Please do not reply directly to my comments, as that feature is not supported yet.

Caution

Do not close the pull request until the review is complete. Closing it early can lead to unexpected behavior and disrupt the review process.

Footnotes

  1. Rate AI review example

  2. Re-request AI review example

  3. Add AI review comments example

const fs = require('fs');
const path = require('path');

function move() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good start on the move function. However, the task requirements point towards an asynchronous implementation. You are expected to use promise-based methods like fs.promises.stat() and fs.promises.unlink().

Consider refactoring this function to be an async function. This will allow you to use await to handle asynchronous operations cleanly and is a best practice in Node.js to avoid blocking the event loop with synchronous I/O operations like fs.statSync or fs.renameSync.


if (!fs.existsSync(sourceFile)) {
// eslint-disable-next-line no-console
console.error('Non-existent source file');

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The task requires that an error must be thrown if the source file does not exist. Currently, you are logging a message to console.error and then returning from the function.

While this informs the user, it doesn't behave like a thrown error (e.g., it results in a successful process exit code 0). Please change this to throw new Error('Non-existent source file');. This applies to all the error conditions in your code.


const dirName = path.dirname(destinationFile);

if (!fs.existsSync(dirName)) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check for the destination directory has a logical flaw. If destinationFile is a path like 'non-existent-dir/', path.dirname('non-existent-dir/') resolves to '.' (the current directory), which almost always exists. This check will pass, but the fs.renameSync call later will fail with an unhandled error because the directory doesn't exist.

You need a more robust way to validate the destination path. If destinationFile ends with a path separator, you should check if that path itself exists and is a directory.

) {
const newFilePath = path.join(normalizedDest, path.basename(sourceFile));

fs.renameSync(sourceFile, newFilePath);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the most critical issue. The task requires the "move" operation to be implemented as a two-step process:

  1. Copy the source file to the destination using streams (fs.createReadStream piped to fs.createWriteStream).
  2. Delete the original source file using fs.promises.unlink() only after the copy is successful.

Using fs.renameSync does not meet these specific technical requirements. You'll need to replace all instances of fs.renameSync with the stream-based copying logic followed by unlinking the source file.

Copy link

@mateacademy-ai-mentor mateacademy-ai-mentor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

Thank you for your submission. While the argument parsing and path handling logic is well-implemented, I'm requesting changes because the core file operations do not yet meet the task's technical requirements.

Here are the main points to address:

  1. Use fs.promises: The task requires using the asynchronous fs.promises API for all file system operations. Please convert your move function to be async and replace synchronous calls like fs.existsSync with their promise-based counterparts using await.
  2. Implement Move via Copy-and-Delete: The use of fs.renameSync is not permitted. The move operation must be implemented by first copying the file using streams (fs.createReadStream and fs.createWriteStream) and then, upon successful copy, deleting the original file with await fs.unlink(sourceFile).
  3. Throw Errors: Instead of logging errors with console.error, the application must throw an error in failure cases. For example, console.error('Non-existent source file'); should be replaced with throw new Error('Non-existent source file');.

✨ Please rate this review in the Platform's notification center1. I will be grateful for your feedback! ✨

Important

Fix the issues, commit the changes, and then re-request my review using the Re-request review button2 in the Reviewers tab.

Tip

If you have any comments about this review, please leave a message in the Add a comment section below and mention me with the @mateacademy-ai-mentor tag3.
I will read your message during my next review of your pull request. Please do not reply directly to my comments, as that feature is not supported yet.

Caution

Do not close the pull request until the review is complete. Closing it early can lead to unexpected behavior and disrupt the review process.

Footnotes

  1. Rate AI review example

  2. Re-request AI review example

  3. Add AI review comments example

@@ -1 +1,77 @@
// write code here
const fs = require('fs');

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The task requires using the asynchronous fs.promises API for all file system operations. Please import it instead of the synchronous fs module. You can achieve this by changing this line to const fs = require('fs').promises;.

const fs = require('fs');
const path = require('path');

function move() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To correctly use the fs.promises API, this function should be declared as async. This will allow you to use await with the promise-based methods, making the code non-blocking and easier to read. For example: async function move() { ... }.

Comment on lines +23 to +27
if (!fs.existsSync(sourceFile)) {
// eslint-disable-next-line no-console
console.error('Non-existent source file');

return;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The requirements state that your application must throw an error in failure cases, not just log to the console. This is crucial for error handling in larger applications and for testing. Please replace the console.error and return with throw new Error('Non-existent source file');. This change should be applied to all error checks in this file.

) {
const newFilePath = path.join(normalizedDest, path.basename(sourceFile));

fs.renameSync(sourceFile, newFilePath);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned in the previous review, using fs.renameSync is not permitted for this task. The goal is to implement the move operation manually by copying the file and then deleting the original.

You should implement this by:

  1. Creating a read stream for the source file (fs.createReadStream).
  2. Creating a write stream for the destination file (fs.createWriteStream).
  3. Using stream.pipeline to connect them, which handles the data transfer and error handling properly.
  4. After the pipeline successfully completes, deleting the source file using await fs.unlink(sourceFile).

src/app.js Outdated
Comment on lines 65 to 70
const renameFile = path.join(
path.dirname(normalizedSource),
path.basename(destinationFile),
);

fs.renameSync(sourceFile, renameFile);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In addition to using the forbidden fs.renameSync method, there's a logical error in how the destination path is constructed here.

path.dirname(normalizedSource) resolves to the directory of the source file, not the destination. This means your code would attempt to rename the file within its original folder instead of moving it to the target location.

For example, mv ./dir1/fileA.txt ./dir2/fileB.txt would incorrectly result in ./dir1/fileB.txt instead of the expected ./dir2/fileB.txt. The correct destination for the new file is already available in your normalizedDest variable.

Copy link

@mateacademy-ai-mentor mateacademy-ai-mentor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

Great job structuring the argument parsing and handling different path scenarios! I'm approving this submission as an educational step to help you move forward, but it's important to review the core requirements as they haven't been met yet.

Please focus on these key areas for your next task:

  1. Asynchronous Operations: The task requires using the fs.promises module for all file system interactions. Your current code uses synchronous methods like fs.existsSync. Remember to make your functions async to use await.
  2. Stream-Based Move: The use of fs.renameSync is explicitly forbidden. The main goal is to implement the move by first copying the file using fs.createReadStream().pipe(fs.createWriteStream()) and then deleting the original with await fs.unlink().
  3. Correct Error Handling: Instead of logging errors with console.error, the application must throw new Error('message') to signal failure correctly.

Mastering these concepts is a crucial part of Node.js development. Keep up the great effort!


✨ Please rate this review in the Platform's notification center1. I will be grateful for your feedback! ✨

Footnotes

  1. Rate AI review example

@@ -1 +1,65 @@
// write code here
const fs = require('fs');

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The task requires using the promise-based fs module. You should import it like this: const fs = require('fs').promises;. This will give you access to asynchronous methods that you can use with await.

const fs = require('fs');
const path = require('path');

function move() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you'll be using await with methods from fs.promises, this function needs to be declared as async. For example: async function move() { ... }.

Comment on lines +7 to +9
console.error(
'Wrong number of arguments is supplied, should pass 2 arguments',
);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned in the previous review, the application must throw an error when something goes wrong, not just log to the console. This allows the calling code (or the Node.js runtime) to know that the operation failed. Please replace this with throw new Error('...');. This applies to all error handling in this file.


const [sourceFile, destinationFile] = process.argv.slice(2);

if (!fs.existsSync(sourceFile)) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a synchronous call. The requirements state that you must use the fs.promises API for file system operations. After importing fs.promises, you could check for file existence asynchronously. A common way is to try to access it and catch any error. For example: try { await fs.access(sourceFile); } catch { throw new Error('Non-existent source file'); }.


const dirName = path.dirname(destinationFile);

if (!fs.existsSync(dirName)) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are two issues here. First, this is a synchronous call and should be replaced with an asynchronous one from fs.promises. Second, this logic is incorrect for destination paths that end with a separator, like nonexistent/. In that case, path.dirname returns . which always exists, and your check fails to catch that the nonexistent directory is missing. You'll need to handle this case specifically before attempting the move.

Comment on lines +45 to +58
fs.renameSync(sourceFile, newFilePath);

return;
}

if (destinationFile.endsWith(path.sep)) {
const newFilePath = path.join(normalizedDest, path.basename(sourceFile));

fs.renameSync(sourceFile, newFilePath);

return;
}

fs.renameSync(sourceFile, normalizedDest);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the most critical part of the feedback. The task explicitly forbids using fs.rename() or fs.renameSync. The 'move' operation must be implemented by:

  1. Creating a readable stream from the sourceFile using fs.createReadStream().
  2. Creating a writable stream to the new destination path using fs.createWriteStream().
  3. Piping the read stream to the write stream to copy the file content.
  4. Once the copy is complete (you can wrap the stream logic in a Promise), you must delete the original sourceFile using await fs.unlink(sourceFile).

Please replace all fs.renameSync calls with this stream-based copy-and-delete logic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants