@@ -88,6 +88,7 @@ using v8::FunctionCallbackInfo;
88
88
using v8::FunctionTemplate;
89
89
using v8::HandleScope;
90
90
using v8::Integer;
91
+ using v8::Isolate;
91
92
using v8::Local;
92
93
using v8::MaybeLocal;
93
94
using v8::Number;
@@ -157,6 +158,15 @@ FSReqAfterScope::~FSReqAfterScope() {
157
158
wrap_->Dispose ();
158
159
}
159
160
161
+ // TODO(joyeecheung): create a normal context object, and
162
+ // construct the actual errors in the JS land using the context.
163
+ // The context should include fds for some fs APIs, currently they are
164
+ // missing in the error messages. The path, dest, syscall, fd, .etc
165
+ // can be put into the context before the binding is even invoked,
166
+ // the only information that has to come from the C++ layer is the
167
+ // error number (and possibly the syscall for abstraction),
168
+ // which is also why the errors should have been constructed
169
+ // in JS for more flexibility.
160
170
void FSReqAfterScope::Reject (uv_fs_t * req) {
161
171
wrap_->Reject (UVException (wrap_->env ()->isolate (),
162
172
req->result ,
@@ -354,28 +364,28 @@ inline FSReqWrap* AsyncCall(Environment* env, Local<Object> req,
354
364
#define ASYNC_CALL (after, func, req, encoding, ...) \
355
365
ASYNC_DEST_CALL (after, func, req, nullptr , encoding, __VA_ARGS__) \
356
366
357
- // Template counterpart of SYNC_DEST_CALL
367
+ // Template counterpart of SYNC_CALL, except that it only puts
368
+ // the error number and the syscall in the context instead of
369
+ // creating an error in the C++ land.
358
370
template <typename Func, typename ... Args>
359
- inline void SyncDestCall (Environment* env, Local<Value> ctx,
360
- const char * path, const char * dest, const char * syscall,
361
- Func fn, Args... args) {
371
+ inline void SyncCall (Environment* env, Local<Value> ctx,
372
+ const char * syscall, Func fn, Args... args) {
362
373
fs_req_wrap req_wrap;
363
374
env->PrintSyncTrace ();
364
375
int err = fn (env->event_loop (), &req_wrap.req , args..., nullptr );
365
- if (err) {
376
+ if (err < 0 ) {
366
377
Local<Context> context = env->context ();
367
378
Local<Object> ctx_obj = ctx->ToObject (context).ToLocalChecked ();
368
- env->CollectUVExceptionInfo (ctx_obj, err, syscall , nullptr , path, dest);
379
+ Isolate *isolate = env->isolate ();
380
+ ctx_obj->Set (context,
381
+ env->errno_string (),
382
+ Integer::New (isolate, err)).FromJust ();
383
+ ctx_obj->Set (context,
384
+ env->syscall_string (),
385
+ OneByteString (isolate, syscall )).FromJust ();
369
386
}
370
387
}
371
388
372
- // Template counterpart of SYNC_CALL
373
- template <typename Func, typename ... Args>
374
- inline void SyncCall (Environment* env, Local<Value> ctx,
375
- const char * path, const char * syscall, Func fn, Args... args) {
376
- return SyncDestCall (env, ctx, path, nullptr , syscall , fn, args...);
377
- }
378
-
379
389
#define SYNC_DEST_CALL (func, path, dest, ...) \
380
390
fs_req_wrap req_wrap; \
381
391
env->PrintSyncTrace (); \
@@ -404,15 +414,15 @@ void Access(const FunctionCallbackInfo<Value>& args) {
404
414
BufferValue path (env->isolate (), args[0 ]);
405
415
int mode = static_cast <int >(args[1 ]->Int32Value (context).FromJust ());
406
416
407
- if (args[2 ]->IsObject ()) {
417
+ if (args[2 ]->IsObject ()) { // access(path, mode, req)
408
418
Local<Object> req_obj = args[2 ]->ToObject (context).ToLocalChecked ();
409
419
FSReqWrap* req_wrap = AsyncCall (
410
420
env, req_obj, UTF8, " access" , AfterNoArgs, uv_fs_access, *path, mode);
411
421
if (req_wrap != nullptr ) {
412
422
args.GetReturnValue ().Set (req_wrap->persistent ());
413
423
}
414
- } else {
415
- SyncCall (env, args[3 ], *path, " access" , uv_fs_access, *path, mode);
424
+ } else { // access(path, mode, undefined, ctx)
425
+ SyncCall (env, args[3 ], " access" , uv_fs_access, *path, mode);
416
426
}
417
427
}
418
428
0 commit comments