0

I have an express app managed via PM2 deployed to an Ubuntu Server. At a certain point an endpoint receives and saves some files in this way

fs.access(path.join(__dirname, '..', 'static', 'images', 'users', userId), (error) => {
  if (error) {
    fs.mkdirSync(path.join(__dirname, '..', 'static', 'images', 'users', userId));
  }
});

But the process crashes. From the logs I can see:

0|App | node:internal/fs/utils:344
0|App |     throw err;
0|App |     ^
0|App |
0|App | Error: ENOENT: no such file or directory, mkdir '/var/www/services.my-app.it/static/images/users/Vtk7xRzSU0fmaqyViTbv5ItQTXs2'
0|App |     at Object.mkdirSync (node:fs:1334:3)
0|App |     at /var/www/services.my-app.it/dist/index.js:1:11558
0|App |     at FSReqCallback.oncomplete (node:fs:188:23) {
0|App |   errno: -2,
0|App |   syscall: 'mkdir',
0|App |   code: 'ENOENT',
0|App |   path: '/var/www/services.my-app.it/static/images/users/Vtk7xRzSU0fmaqyViTbv5ItQTXs2'
0|App | }
0|App | error Command failed with exit code 1.

It's clearly a permissions problem, however I can't figure out what is the user that needs the permission in order to solve the problem.

I tried to launch the process via pm2 start both from root and personal user, nothing changes.

▶ ll
total 312K
drwxr-xr-x   2 root  root  4.0K May  4 12:15 dist
-rw-rw-r--   1 thefe thefe 1.1K May  2 15:18 index.js
-rw-rw-r--   1 thefe thefe  440 May  2 14:55 jsconfig.json
drwxrwxr-x 485 thefe thefe  20K May  2 14:56 node_modules
-rw-rw-r--   1 thefe thefe 1.4K May  2 14:55 package.json
-rw-rw-r--   1 thefe thefe 2.3K Apr 15  2022 service-account.json
drwxrwxr-x   7 thefe thefe 4.0K Apr  9 19:59 src
drwxrwxrwx   2 root  root  4.0K May  4 09:48 static
-rw-rw-r--   1 thefe thefe 1012 May  2 14:55 webpack.config.js
-rw-rw-r--   1 thefe thefe 259K May  2 14:55 yarn.lock

1 Answer 1

0

Ok, I figured it out! It wasn't actually a permissions problem (that were configured correctly), but actually the { recursive: true } was missing from the fs.mkdirSync, and so Node wasn't able to create the subfolders. Adding that solved the problem.

UPDATED CODE IS:

fs.access(path.join(__dirname, '..', 'static', 'images', 'users', userId), (error) => {
  if (error) {
    fs.mkdirSync(path.join(__dirname, '..', 'static', 'images', 'users', userId), { recursive: true });
  }
});

After some researches I found a new way to do what I'm doing with new NodeJS functions. I created a utility method, credits go to this answer

import { stat, mkdir } from 'node:fs/promises';

const checkAndMakeDir = async (dir) => {
  try {
    await stat(dir);
  } catch (error) {
    if (error.code === 'ENOENT') {
      try {
        await mkdir(dir, { recursive: true });
      } catch (err) {
        console.error(err.message);
      }
    }
  }
};

export default checkAndMakeDir;

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.