Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

file: fix errno propagation in sync fs calls

Include libuv fs error code in the JS exception.

Fixes #1657.
  • Loading branch information...
commit 2d9ab49239d475cad3126384daefc6f365555dd9 1 parent 554dc63
@bnoordhuis bnoordhuis authored
View
67 src/node_file.cc
@@ -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_, \
@@ -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
View
2  test/simple/test-fs-open.js
@@ -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);
View
1  test/simple/test-net-connect-handle-econnrefused.js
@@ -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);
});
Please sign in to comment.
Something went wrong with that request. Please try again.