summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJoyee Cheung <joyeec9h3@gmail.com>2017-11-21 04:47:57 +0800
committerJoyee Cheung <joyeec9h3@gmail.com>2017-11-25 22:33:42 +0900
commit07d34092b117c4b5bdad85cf916d9ae5e213651d (patch)
treeeb4a17da4c4bdbb23dd3c7893804a6d8191b2b2d /src
parent73154c0341145985ac7e9b61841a58805d82f533 (diff)
downloadandroid-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.cc68
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);
}
}