From 99b3dbb7984f2f3612e9b52c0e723235551428fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Habov=C5=A1tiak?= Date: Sun, 3 May 2020 21:54:26 +0200 Subject: [PATCH] Fixed error handling in createDirecctory (#311) The error handling in `createDirecctory` had three major issues: * Racy check for existence of a directory - the directory could've been created or deleted in the meantime. * Attempt to handle race outside the reduce function wouldn't let it continue creating the remaining directories. * All errors that were **not** `EEXISTS` or `ENOENT` were silently ignored, leading to lot of frustration and hair pulling, because the code continued executing and then failed at attempt to open a file. These problems were fixed by moving `try` into the reduce closure, ignoring `EEXISTS` only and rethrowing all other errors. The logic modifying the error message for `ENOENT` was kept. --- connect.js | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/connect.js b/connect.js index 4aeba112..c46adc25 100644 --- a/connect.js +++ b/connect.js @@ -230,23 +230,22 @@ connect.setSSOParams = (config) => { }; connect.createDirectory = (dirname) => { - try { - const initDir = path.isAbsolute(dirname) ? path.sep : ''; - dirname.split(path.sep).reduce((parentDir, childDir) => { - const curDir = path.resolve(parentDir, childDir); - if (!fs.existsSync(curDir)) { - fs.mkdirSync(curDir); + const initDir = path.isAbsolute(dirname) ? path.sep : ''; + dirname.split(path.sep).reduce((parentDir, childDir) => { + const curDir = path.resolve(parentDir, childDir); + try { + fs.mkdirSync(curDir); + } catch (err) { + if (err.code !== 'EEXIST') { + if (err.code === 'ENOENT') { + throw new Error(`ENOENT: No such file or directory, mkdir '${dirname}'. Ensure that channel backup path separator is '${(platform === 'win32') ? '\\\\' : '/'}'`); + } else { + throw err; + } } - return curDir; - }, initDir); - } catch (err) { - if (err.code === 'EEXIST') { - return dirname; } - if (err.code === 'ENOENT') { - throw new Error(`ENOENT: No such file or directory, mkdir '${dirname}'. Ensure that channel backup path separator is '${(platform === 'win32') ? '\\\\' : '/'}'`); - } - } + return curDir; + }, initDir); } connect.readCookie = (cookieFile) => {