diff --git a/lib/fs.js b/lib/fs.js index da718f3f334413..6129e3c3ef35a0 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -108,6 +108,20 @@ function copyObject(source) { return target; } +function handleErrorFromBinding(ctx) { + if (ctx.errno !== undefined) { // libuv error numbers + const err = errors.uvException(ctx); + Error.captureStackTrace(err, handleErrorFromBinding); + throw err; + } else if (ctx.error !== undefined) { // errors created in C++ land. + // TODO(joyeecheung): currently, ctx.error are encoding errors + // usually caused by memory problems. We need to figure out proper error + // code(s) for this. + Error.captureStackTrace(ctx.error, handleErrorFromBinding); + throw ctx.error; + } +} + // TODO(joyeecheung): explore how the deprecation could be solved via linting // rules. See https://github.com/nodejs/node/pull/12976 function rethrow() { @@ -405,10 +419,7 @@ fs.accessSync = function(path, mode) { const ctx = { path }; binding.access(pathModule.toNamespacedPath(path), mode, undefined, ctx); - - if (ctx.errno !== undefined) { - throw errors.uvException(ctx); - } + handleErrorFromBinding(ctx); }; // fs.exists never throws even when the arguments are invalid - if there is @@ -742,9 +753,7 @@ fs.closeSync = function(fd) { const ctx = {}; binding.close(fd, undefined, ctx); - if (ctx.errno !== undefined) { - throw errors.uvException(ctx); - } + handleErrorFromBinding(ctx); }; function modeNum(m, def) { @@ -924,9 +933,7 @@ fs.renameSync = function(oldPath, newPath) { const ctx = { path: oldPath, dest: newPath }; binding.rename(pathModule.toNamespacedPath(oldPath), pathModule.toNamespacedPath(newPath), undefined, ctx); - if (ctx.errno !== undefined) { - throw errors.uvException(ctx); - } + handleErrorFromBinding(ctx); }; fs.truncate = function(path, len, callback) { @@ -994,9 +1001,7 @@ fs.ftruncateSync = function(fd, len = 0) { len = Math.max(0, len); const ctx = {}; binding.ftruncate(fd, len, undefined, ctx); - if (ctx.errno !== undefined) { - throw errors.uvException(ctx); - } + handleErrorFromBinding(ctx); }; fs.rmdir = function(path, callback) { @@ -1025,9 +1030,7 @@ fs.fdatasyncSync = function(fd) { validateUint32(fd, 'fd'); const ctx = {}; binding.fdatasync(fd, undefined, ctx); - if (ctx.errno !== undefined) { - throw errors.uvException(ctx); - } + handleErrorFromBinding(ctx); }; fs.fsync = function(fd, callback) { @@ -1041,9 +1044,7 @@ fs.fsyncSync = function(fd) { validateUint32(fd, 'fd'); const ctx = {}; binding.fsync(fd, undefined, ctx); - if (ctx.errno !== undefined) { - throw errors.uvException(ctx); - } + handleErrorFromBinding(ctx); }; fs.mkdir = function(path, mode, callback) { @@ -1114,9 +1115,7 @@ fs.fstatSync = function(fd) { validateUint32(fd, 'fd'); const ctx = { fd }; binding.fstat(fd, undefined, ctx); - if (ctx.errno !== undefined) { - throw errors.uvException(ctx); - } + handleErrorFromBinding(ctx); return statsFromValues(); }; @@ -1125,9 +1124,7 @@ fs.lstatSync = function(path) { validatePath(path); const ctx = { path }; binding.lstat(pathModule.toNamespacedPath(path), undefined, ctx); - if (ctx.errno !== undefined) { - throw errors.uvException(ctx); - } + handleErrorFromBinding(ctx); return statsFromValues(); }; @@ -1136,9 +1133,7 @@ fs.statSync = function(path) { validatePath(path); const ctx = { path }; binding.stat(pathModule.toNamespacedPath(path), undefined, ctx); - if (ctx.errno !== undefined) { - throw errors.uvException(ctx); - } + handleErrorFromBinding(ctx); return statsFromValues(); }; @@ -1159,14 +1154,7 @@ fs.readlinkSync = function(path, options) { const ctx = { path }; const result = binding.readlink(pathModule.toNamespacedPath(path), options.encoding, undefined, ctx); - if (ctx.errno !== undefined) { - throw errors.uvException(ctx); - } else if (ctx.error) { - // TODO(joyeecheung): this is an encoding error usually caused by memory - // problems. We need to figure out proper error code(s) for this. - Error.captureStackTrace(ctx.error); - throw ctx.error; - } + handleErrorFromBinding(ctx); return result; }; @@ -1235,9 +1223,7 @@ fs.symlinkSync = function(target, path, type) { binding.symlink(preprocessSymlinkDestination(target, type, path), pathModule.toNamespacedPath(path), flags, undefined, ctx); - if (ctx.errno !== undefined) { - throw errors.uvException(ctx); - } + handleErrorFromBinding(ctx); }; fs.link = function(existingPath, newPath, callback) { @@ -1266,9 +1252,7 @@ fs.linkSync = function(existingPath, newPath) { const result = binding.link(pathModule.toNamespacedPath(existingPath), pathModule.toNamespacedPath(newPath), undefined, ctx); - if (ctx.errno !== undefined) { - throw errors.uvException(ctx); - } + handleErrorFromBinding(ctx); return result; }; @@ -1286,9 +1270,7 @@ fs.unlinkSync = function(path) { validatePath(path); const ctx = { path }; binding.unlink(pathModule.toNamespacedPath(path), undefined, ctx); - if (ctx.errno !== undefined) { - throw errors.uvException(ctx); - } + handleErrorFromBinding(ctx); }; fs.fchmod = function(fd, mode, callback) { @@ -1887,9 +1869,7 @@ fs.realpathSync = function realpathSync(p, options) { if (isWindows && !knownHard[base]) { const ctx = { path: base }; binding.lstat(pathModule.toNamespacedPath(base), undefined, ctx); - if (ctx.errno !== undefined) { - throw errors.uvException(ctx); - } + handleErrorFromBinding(ctx); knownHard[base] = true; } @@ -1931,9 +1911,7 @@ fs.realpathSync = function realpathSync(p, options) { var baseLong = pathModule.toNamespacedPath(base); const ctx = { path: base }; binding.lstat(baseLong, undefined, ctx); - if (ctx.errno !== undefined) { - throw errors.uvException(ctx); - } + handleErrorFromBinding(ctx); if ((statValues[1/*mode*/] & S_IFMT) !== S_IFLNK) { knownHard[base] = true; @@ -1956,13 +1934,9 @@ fs.realpathSync = function realpathSync(p, options) { if (linkTarget === null) { const ctx = { path: base }; binding.stat(baseLong, undefined, ctx); - if (ctx.errno !== undefined) { - throw errors.uvException(ctx); - } + handleErrorFromBinding(ctx); linkTarget = binding.readlink(baseLong, undefined, undefined, ctx); - if (ctx.errno !== undefined) { - throw errors.uvException(ctx); - } + handleErrorFromBinding(ctx); } resolvedLink = pathModule.resolve(previous, linkTarget); @@ -1981,9 +1955,7 @@ fs.realpathSync = function realpathSync(p, options) { if (isWindows && !knownHard[base]) { const ctx = { path: base }; binding.lstat(pathModule.toNamespacedPath(base), undefined, ctx); - if (ctx.errno !== undefined) { - throw errors.uvException(ctx); - } + handleErrorFromBinding(ctx); knownHard[base] = true; } }