Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
file: fix errno propagation in sync fs calls
Include libuv fs error code in the JS exception.

Fixes #1657.
  • Loading branch information
bnoordhuis committed Sep 6, 2011
1 parent 554dc63 commit 2d9ab49
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 4 deletions.
67 changes: 65 additions & 2 deletions src/node_file.cc
Expand Up @@ -213,6 +213,69 @@ struct fs_req_wrap {
uv_fs_t req;
};


const char* errno_string(int errorno) {
uv_err_t err;
memset(&err, 0, sizeof err);
err.code = (uv_err_code)errorno;
return uv_err_name(err);
}


const char* errno_message(int errorno) {
uv_err_t err;
memset(&err, 0, sizeof err);
err.code = (uv_err_code)errorno;
return uv_strerror(err);
}


// hack alert! copy of ErrnoException in node.cc, tuned for uv errors
Local<Value> FSError(int errorno,
const char *syscall,
const char *msg,
const char *path) {
static Persistent<String> syscall_symbol;
static Persistent<String> errpath_symbol;
static Persistent<String> code_symbol;

if (syscall_symbol.IsEmpty()) {
syscall_symbol = NODE_PSYMBOL("syscall");
errno_symbol = NODE_PSYMBOL("errno");
errpath_symbol = NODE_PSYMBOL("path");
code_symbol = NODE_PSYMBOL("code");
}

if (!msg || !msg[0])
msg = errno_message(errorno);

Local<String> estring = String::NewSymbol(errno_string(errorno));
Local<String> message = String::NewSymbol(msg);
Local<String> cons1 = String::Concat(estring, String::NewSymbol(", "));
Local<String> cons2 = String::Concat(cons1, message);

Local<Value> e;

if (path) {
Local<String> cons3 = String::Concat(cons2, String::NewSymbol(" '"));
Local<String> cons4 = String::Concat(cons3, String::New(path));
Local<String> cons5 = String::Concat(cons4, String::NewSymbol("'"));
e = Exception::Error(cons5);
} else {
e = Exception::Error(cons2);
}

Local<Object> obj = e->ToObject();

// TODO errno should probably go
obj->Set(errno_symbol, Integer::New(errorno));
obj->Set(code_symbol, estring);
if (path) obj->Set(errpath_symbol, String::New(path));
if (syscall) obj->Set(syscall_symbol, String::NewSymbol(syscall));
return e;
}


#define ASYNC_CALL(func, callback, ...) \
FSReqWrap* req_wrap = new FSReqWrap(); \
int r = uv_fs_##func(uv_default_loop(), &req_wrap->req_, \
Expand All @@ -226,8 +289,8 @@ struct fs_req_wrap {
fs_req_wrap req_wrap; \
uv_fs_##func(uv_default_loop(), &req_wrap.req, __VA_ARGS__, NULL); \
if (req_wrap.req.result < 0) { \
return ThrowException( \
ErrnoException(req_wrap.req.errorno, #func, "", path)); \
int code = uv_last_error(uv_default_loop()).code; \
return ThrowException(FSError(code, #func, "", path)); \
}

#define SYNC_REQ req_wrap.req
Expand Down
2 changes: 1 addition & 1 deletion test/simple/test-fs-open.js
Expand Up @@ -30,7 +30,7 @@ try {
fs.openSync('/path/to/file/that/does/not/exist', 'r');
}
catch (e) {
assert.equal(e.errno, constants.ENOENT);
assert.equal(e.code, 'ENOENT');
caughtException = true;
}
assert.ok(caughtException);
Expand Down
1 change: 0 additions & 1 deletion test/simple/test-net-connect-handle-econnrefused.js
Expand Up @@ -39,7 +39,6 @@ var gotError = false;
c.on('error', function(e) {
console.error('couldn\'t connect.');
gotError = true;
assert.equal(require('constants').ECONNREFUSED, e.errno);
assert.equal('ECONNREFUSED', e.code);
});

Expand Down

0 comments on commit 2d9ab49

Please sign in to comment.