fs: extract binding error handling into a helper

PR-URL: https://github.com/nodejs/node/pull/18642
Reviewed-By: Jon Moss <me@jonathanmoss.me>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
This commit is contained in:
Joyee Cheung 2018-02-08 22:24:08 +08:00
parent 18d23aa36e
commit b2e20b002b
No known key found for this signature in database
GPG Key ID: F586868AAD831D0C

View File

@ -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;
}
}