| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1719,6 +1719,9 @@ changes: | |||
| 1719 | 1719 | * `options` {Object} | |
| 1720 | 1720 | * `bigint` {boolean} Whether the numeric values in the returned | |
| 1721 | 1721 | {fs.Stats} object should be `bigint`. **Default:** `false`. | |
| 1722 | + * `throwIfNoEntry` {boolean} Whether an exception will be thrown | ||
| 1723 | + if no file system entry exists, rather than returning `undefined`. | ||
| 1724 | + **Default:** `true`. | ||
| 1722 | 1725 | * Returns: {Promise} Fulfills with the {fs.Stats} object for the | |
| 1723 | 1726 | given `path`. | |
| 1724 | 1727 | ||
@@ -4436,6 +4439,9 @@ changes: | |||
| 4436 | 4439 | * `options` {Object} | |
| 4437 | 4440 | * `bigint` {boolean} Whether the numeric values in the returned | |
| 4438 | 4441 | {fs.Stats} object should be `bigint`. **Default:** `false`. | |
| 4442 | + * `throwIfNoEntry` {boolean} Whether an exception will be thrown | ||
| 4443 | + if no file system entry exists, rather than returning `undefined`. | ||
| 4444 | + **Default:** `true`. | ||
| 4439 | 4445 | * `callback` {Function} | |
| 4440 | 4446 | * `err` {Error} | |
| 4441 | 4447 | * `stats` {fs.Stats} | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -188,6 +188,7 @@ function makeStatsCallback(cb) { | |||
| 188 | 188 | ||
| 189 | 189 | return (err, stats) => { | |
| 190 | 190 | if (err) return cb(err); | |
| 191 | + if (stats === undefined && err === null) return cb(null, undefined); | ||
| 191 | 192 | cb(err, getStatsFromBinding(stats)); | |
| 192 | 193 | }; | |
| 193 | 194 | } | |
@@ -1621,7 +1622,7 @@ function lstat(path, options = { bigint: false }, callback) { | |||
| 1621 | 1622 | * ) => any} callback | |
| 1622 | 1623 | * @returns {void} | |
| 1623 | 1624 | */ | |
| 1624 | - function stat(path, options = { bigint: false }, callback) { | ||
| 1625 | + function stat(path, options = { bigint: false, throwIfNoEntry: true }, callback) { | ||
| 1625 | 1626 | if (typeof options === 'function') { | |
| 1626 | 1627 | callback = options; | |
| 1627 | 1628 | options = kEmptyObject; | |
@@ -1630,7 +1631,7 @@ function stat(path, options = { bigint: false }, callback) { | |||
| 1630 | 1631 | ||
| 1631 | 1632 | const req = new FSReqCallback(options.bigint); | |
| 1632 | 1633 | req.oncomplete = callback; | |
| 1633 | - binding.stat(getValidatedPath(path), options.bigint, req); | ||
| 1634 | + binding.stat(getValidatedPath(path), options.bigint, req, options.throwIfNoEntry); | ||
| 1634 | 1635 | } | |
| 1635 | 1636 | ||
| 1636 | 1637 | function statfs(path, options = { bigint: false }, callback) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1026,12 +1026,16 @@ async function lstat(path, options = { bigint: false }) { | |||
| 1026 | 1026 | return getStatsFromBinding(result); | |
| 1027 | 1027 | } | |
| 1028 | 1028 | ||
| 1029 | - async function stat(path, options = { bigint: false }) { | ||
| 1029 | + async function stat(path, options = { bigint: false, throwIfNoEntry: true }) { | ||
| 1030 | 1030 | const result = await PromisePrototypeThen( | |
| 1031 | - binding.stat(getValidatedPath(path), options.bigint, kUsePromises), | ||
| 1031 | + binding.stat(getValidatedPath(path), options.bigint, kUsePromises, options.throwIfNoEntry), | ||
| 1032 | 1032 | undefined, | |
| 1033 | 1033 | handleErrorFromBinding, | |
| 1034 | 1034 | ); | |
| 1035 | + | ||
| 1036 | + // Binding will resolve undefined if UV_ENOENT or UV_ENOTDIR and throwIfNoEntry is false | ||
| 1037 | + if (!options.throwIfNoEntry && result === undefined) return undefined; | ||
| 1038 | + | ||
| 1035 | 1039 | return getStatsFromBinding(result); | |
| 1036 | 1040 | } | |
| 1037 | 1041 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -810,6 +810,22 @@ void AfterStat(uv_fs_t* req) { | |||
| 810 | 810 | } | |
| 811 | 811 | } | |
| 812 | 812 | ||
| 813 | + void AfterStatNoThrowIfNoEntry(uv_fs_t* req) { | ||
| 814 | + FSReqBase* req_wrap = FSReqBase::from_req(req); | ||
| 815 | + FSReqAfterScope after(req_wrap, req); | ||
| 816 | + | ||
| 817 | + FS_ASYNC_TRACE_END1( | ||
| 818 | + req->fs_type, req_wrap, "result", static_cast<int>(req->result)) | ||
| 819 | + if (req->result == UV_ENOENT || req->result == UV_ENOTDIR) { | ||
| 820 | + req_wrap->Resolve(Undefined(req_wrap->env()->isolate())); | ||
| 821 | + return; | ||
| 822 | + } | ||
| 823 | + | ||
| 824 | + if (after.Proceed()) { | ||
| 825 | + req_wrap->ResolveStat(&req->statbuf); | ||
| 826 | + } | ||
| 827 | + } | ||
| 828 | + | ||
| 813 | 829 | void AfterStatFs(uv_fs_t* req) { | |
| 814 | 830 | FSReqBase* req_wrap = FSReqBase::from_req(req); | |
| 815 | 831 | FSReqAfterScope after(req_wrap, req); | |
@@ -1105,7 +1121,9 @@ static void Stat(const FunctionCallbackInfo<Value>& args) { | |||
| 1105 | 1121 | ToNamespacedPath(env, &path); | |
| 1106 | 1122 | ||
| 1107 | 1123 | bool use_bigint = args[1]->IsTrue(); | |
| 1108 | - if (!args[2]->IsUndefined()) { // stat(path, use_bigint, req) | ||
| 1124 | + if (!args[2]->IsUndefined()) { // stat(path, use_bigint, req, | ||
| 1125 | + // do_not_throw_if_no_entry) | ||
| 1126 | + bool do_not_throw_if_no_entry = args[3]->IsFalse(); | ||
| 1109 | 1127 | FSReqBase* req_wrap_async = GetReqWrap(args, 2, use_bigint); | |
| 1110 | 1128 | CHECK_NOT_NULL(req_wrap_async); | |
| 1111 | 1129 | ASYNC_THROW_IF_INSUFFICIENT_PERMISSIONS( | |
@@ -1115,8 +1133,25 @@ static void Stat(const FunctionCallbackInfo<Value>& args) { | |||
| 1115 | 1133 | path.ToStringView()); | |
| 1116 | 1134 | FS_ASYNC_TRACE_BEGIN1( | |
| 1117 | 1135 | UV_FS_STAT, req_wrap_async, "path", TRACE_STR_COPY(*path)) | |
| 1118 | - AsyncCall(env, req_wrap_async, args, "stat", UTF8, AfterStat, | ||
| 1119 | - uv_fs_stat, *path); | ||
| 1136 | + if (do_not_throw_if_no_entry) { | ||
| 1137 | + AsyncCall(env, | ||
| 1138 | + req_wrap_async, | ||
| 1139 | + args, | ||
| 1140 | + "stat", | ||
| 1141 | + UTF8, | ||
| 1142 | + AfterStatNoThrowIfNoEntry, | ||
| 1143 | + uv_fs_stat, | ||
| 1144 | + *path); | ||
| 1145 | + } else { | ||
| 1146 | + AsyncCall(env, | ||
| 1147 | + req_wrap_async, | ||
| 1148 | + args, | ||
| 1149 | + "stat", | ||
| 1150 | + UTF8, | ||
| 1151 | + AfterStat, | ||
| 1152 | + uv_fs_stat, | ||
| 1153 | + *path); | ||
| 1154 | + } | ||
| 1120 | 1155 | } else { // stat(path, use_bigint, undefined, do_not_throw_if_no_entry) | |
| 1121 | 1156 | THROW_IF_INSUFFICIENT_PERMISSIONS( | |
| 1122 | 1157 | env, permission::PermissionScope::kFileSystemRead, path.ToStringView()); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -152,6 +152,12 @@ async function executeOnHandle(dest, func) { | |||
| 152 | 152 | })); | |
| 153 | 153 | } | |
| 154 | 154 | ||
| 155 | + // File stats throwIfNoEntry: false | ||
| 156 | + { | ||
| 157 | + const stats = await stat('meow.js', { throwIfNoEntry: false }); | ||
| 158 | + assert.strictEqual(stats, undefined); | ||
| 159 | + } | ||
| 160 | + | ||
| 155 | 161 | // File system stats | |
| 156 | 162 | { | |
| 157 | 163 | const statFs = await statfs(dest); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -224,5 +224,9 @@ fs.lstat(__filename, undefined, common.mustCall()); | |||
| 224 | 224 | ||
| 225 | 225 | { | |
| 226 | 226 | // Test that the throwIfNoEntry option works and returns undefined | |
| 227 | - assert.ok(!(fs.statSync('./wont_exists', { throwIfNoEntry: false }))); | ||
| 227 | + const opts = { throwIfNoEntry: false }; | ||
| 228 | + assert.ok(!(fs.statSync('./wont_exists', opts))); | ||
| 229 | + fs.stat('./wont_exists', opts, common.mustSucceed((err, stats) => { | ||
| 230 | + assert.strictEqual(stats, undefined); | ||
| 231 | + })); | ||
| 228 | 232 | } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments