Home > Enterprise >  writeFileSync NOT creating and writing to file
writeFileSync NOT creating and writing to file

Time:12-27

So, I have a bunch of SSG pages in Next.js and as such, I am creating the navigation over over which has a bunch of routes. SO, I want to "cache" the first api call and just get the cached (written to file data) after that. I am using this, and it is NOT creating the file. I get the following error and as such, I am always hitting the api.

I log in the catch, and it gives the error. File is never created.

ERROR:

Error: ENOENT: no such file or directory, open '/Users/jim/company/clientapp/.next/server/pages/Users/jim/company/clientapp/.routes'

My code:

import fs from 'fs';
import path from 'path';

/* api */
import routes from '@api/rest/routes';

const ROUTE_CACHE_PATH = path.resolve('.routes');

export default async function getCacheRoutes() {
  let cachedData

  try {
    cachedData = JSON.parse(
      fs.readFileSync(path.join(__dirname, ROUTE_CACHE_PATH), 'utf8')
    )
      } catch (error) {
    // logger here
  }

  if (!cachedData) {    
    const data = await routes() // this is the api request, it works

    try {
      fs.writeFileSync(
        path.join(__dirname, ROUTE_CACHE_PATH),
        JSON.stringify(data),
        { flag: 'w' }. // With or without this, doesn't work.
      )
    } catch (error) {
      // Logger here
    }

    cachedData = data
  }

  return cachedData
}

CodePudding user response:

It fails because the path to the file in ROUTE_CACHE_PATH, and readFileSync is incorrect throughout.

Try setting up the correct path, and then use it throughout:

// setup the correct path to file, use it throughout
// writes to the file `routes` in CWD
const ROUTE_CACHE_PATH = path.resolve(path.join(process.cwd(), 'routes'));

and now reference it throughout:

fs.readFileSync(ROUTE_CACHE_PATH, 'utf8')

and

fs.writeFileSync(
ROUTE_CACHE_PATH,

Bear in mind that JSON.parse might also fail here, if it's not parsable data you send, so you might consider adding a handler for that too, or maybe on the sender part.

With this code, the reading and writing are sort of independent. So, a better way might be to move the file writing in the error part, IMHO:

try {
    readFile
} catch() {
    writeFile
}

Here's the rearranged code:

import fs from 'fs';
import path from 'path';

/* api */
import routes from '@api/rest/routes';

// setup the correct path to file, use it throughout
// writes to the file `routes` in CWD
const ROUTE_CACHE_PATH = path.resolve(path.join(process.cwd(), 'routes'));

export default async function getCacheRoutes() {

  // setup variables to be accessible for later
  let cachedData;
  let data;    

  // first, read the file
  // if it fails, there is no file
  // so move the file writing to the error part
  // note that parsing might also fail, so handle that there too
  try {
    // parsing might fail here though..
    cachedData = JSON.parse(
      fs.readFileSync(ROUTE_CACHE_PATH, 'utf8')
    )
  } catch (error) {

    // reading failed, handle file writing
    // parsing and other errors here
    console.log(error);

    // if there is no file, get data and write a fresh file
    if (error.code === 'ENOENT') {

      // todo: make sure it's always a JSON as string,
      // otherwise parsing will fail..
      data = await routes();

      try {
        fs.writeFileSync(
          ROUTE_CACHE_PATH,
          JSON.stringify(data), {
            flag: 'w'
          }
        )
      } catch (error) {
        // parsing might fail..
        console.log(error);
      }
    } else {
      // or some other error: JSON parsing failed, for example
      console.log('handle some other error', error);
    }

    cachedData = data;

  }

  return cachedData

}
  • Related