diff options
author | Joyee Cheung <joyeec9h3@gmail.com> | 2017-11-21 04:47:57 +0800 |
---|---|---|
committer | Joyee Cheung <joyeec9h3@gmail.com> | 2017-11-25 22:33:42 +0900 |
commit | 07d34092b117c4b5bdad85cf916d9ae5e213651d (patch) | |
tree | eb4a17da4c4bdbb23dd3c7893804a6d8191b2b2d /src | |
parent | 73154c0341145985ac7e9b61841a58805d82f533 (diff) | |
download | android-node-v8-07d34092b117c4b5bdad85cf916d9ae5e213651d.tar.gz android-node-v8-07d34092b117c4b5bdad85cf916d9ae5e213651d.tar.bz2 android-node-v8-07d34092b117c4b5bdad85cf916d9ae5e213651d.zip |
fs: throw fs.access errors in JS
- Migrate the type check of path to ERR_INVALID_ARG_TYPE
- Add template counterparts of ASYNC_CALL, ASYNC_DEST_CALL,
SYNC_CALL, SYNC_DEST_CALL
- Port StringFromPath and UVException to JavaScript
- Migrate the access binding to collect the error context in C++,
then throw the error in JS
PR-URL: https://github.com/nodejs/node/pull/17160
Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/node_file.cc | 68 |
1 files changed, 58 insertions, 10 deletions
diff --git a/src/node_file.cc b/src/node_file.cc index 12a9f411bc..2b3b007976 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -349,6 +349,31 @@ class fs_req_wrap { DISALLOW_COPY_AND_ASSIGN(fs_req_wrap); }; +// Template counterpart of ASYNC_DEST_CALL +template <typename Func, typename... Args> +inline FSReqWrap* AsyncDestCall(Environment* env, Local<Object> req, + const char* dest, enum encoding enc, const char* syscall, + Func fn, Args... args) { + FSReqWrap* req_wrap = FSReqWrap::New(env, req, syscall, dest, enc); + int err = fn(env->event_loop(), req_wrap->req(), args..., After); + req_wrap->Dispatched(); + if (err < 0) { + uv_fs_t* uv_req = req_wrap->req(); + uv_req->result = err; + uv_req->path = nullptr; + After(uv_req); + req_wrap = nullptr; + } + + return req_wrap; +} + +// Template counterpart of ASYNC_CALL +template <typename Func, typename... Args> +inline FSReqWrap* AsyncCall(Environment* env, Local<Object> req, + enum encoding enc, const char* syscall, Func fn, Args... args) { + return AsyncDestCall(env, req, nullptr, enc, syscall, fn, args...); +} #define ASYNC_DEST_CALL(func, request, dest, encoding, ...) \ Environment* env = Environment::GetCurrent(args); \ @@ -373,6 +398,28 @@ class fs_req_wrap { #define ASYNC_CALL(func, req, encoding, ...) \ ASYNC_DEST_CALL(func, req, nullptr, encoding, __VA_ARGS__) \ +// Template counterpart of SYNC_DEST_CALL +template <typename Func, typename... Args> +inline void SyncDestCall(Environment* env, Local<Value> ctx, + const char* path, const char* dest, const char* syscall, + Func fn, Args... args) { + fs_req_wrap req_wrap; + env->PrintSyncTrace(); + int err = fn(env->event_loop(), &req_wrap.req, args..., nullptr); + if (err) { + Local<Context> context = env->context(); + Local<Object> ctx_obj = ctx->ToObject(context).ToLocalChecked(); + env->CollectUVExceptionInfo(ctx_obj, err, syscall, nullptr, path, dest); + } +} + +// Template counterpart of SYNC_CALL +template <typename Func, typename... Args> +inline void SyncCall(Environment* env, Local<Value> ctx, + const char* path, const char* syscall, Func fn, Args... args) { + return SyncDestCall(env, ctx, path, nullptr, syscall, fn, args...); +} + #define SYNC_DEST_CALL(func, path, dest, ...) \ fs_req_wrap req_wrap; \ env->PrintSyncTrace(); \ @@ -394,21 +441,22 @@ class fs_req_wrap { void Access(const FunctionCallbackInfo<Value>& args) { Environment* env = Environment::GetCurrent(args.GetIsolate()); HandleScope scope(env->isolate()); - - if (args.Length() < 2) - return TYPE_ERROR("path and mode are required"); - if (!args[1]->IsInt32()) - return TYPE_ERROR("mode must be an integer"); + Local<Context> context = env->context(); + CHECK_GE(args.Length(), 2); + CHECK(args[1]->IsInt32()); BufferValue path(env->isolate(), args[0]); - ASSERT_PATH(path) - - int mode = static_cast<int>(args[1]->Int32Value()); + int mode = static_cast<int>(args[1]->Int32Value(context).FromJust()); if (args[2]->IsObject()) { - ASYNC_CALL(access, args[2], UTF8, *path, mode); + Local<Object> req_obj = args[2]->ToObject(context).ToLocalChecked(); + FSReqWrap* req_wrap = AsyncCall( + env, req_obj, UTF8, "access", uv_fs_access, *path, mode); + if (req_wrap != nullptr) { + args.GetReturnValue().Set(req_wrap->persistent()); + } } else { - SYNC_CALL(access, *path, *path, mode); + SyncCall(env, args[3], *path, "access", uv_fs_access, *path, mode); } } |