You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ra...@apache.org on 2012/01/27 02:37:13 UTC
[6/7] git commit: COUCHDB-111 and COUCHDB-1389 JS Error Tracebacks
COUCHDB-111 and COUCHDB-1389 JS Error Tracebacks
couchjs:
- report stacktraces on exceptions using JS_ReportError
- responds with a trace and message on errors when possible
- propogate Error-like objects from validate_doc_update to the loop
- make Error-like object play nicely with couch_os_process
couch.js:
- transform HTTP error response bodies into an Error instance to
capture stack information
cli tests:
- print a stacktrace for individual test failures when running the suite
Fix COUCHDB-111
Fix COUCHDB-1389
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/32a11134
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/32a11134
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/32a11134
Branch: refs/heads/master
Commit: 32a1113417c25deee9052e7d3de37cc0faea9914
Parents: 5f55e9f
Author: Randall Leeds <ra...@apache.org>
Authored: Thu Dec 15 19:49:34 2011 -0800
Committer: Randall Leeds <ra...@apache.org>
Committed: Thu Jan 26 17:02:38 2012 -0800
----------------------------------------------------------------------
share/server/loop.js | 2 +
share/server/validate.js | 5 +++-
share/www/script/couch.js | 13 ++++++++-
src/couchdb/priv/couch_js/sm170.c | 2 +
src/couchdb/priv/couch_js/sm180.c | 2 +
src/couchdb/priv/couch_js/sm185.c | 2 +
src/couchdb/priv/couch_js/util.c | 45 +++++++++++++++++++++++++++++++-
test/javascript/cli_runner.js | 19 ++++++-------
8 files changed, 77 insertions(+), 13 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/32a11134/share/server/loop.js
----------------------------------------------------------------------
diff --git a/share/server/loop.js b/share/server/loop.js
index eb7f75b..986c8b3 100644
--- a/share/server/loop.js
+++ b/share/server/loop.js
@@ -140,6 +140,8 @@ var Loop = function() {
} else if (e.error && e.reason) {
// compatibility with old error format
respond(["error", e.error, e.reason]);
+ } else if (e.name) {
+ respond(["error", e.name, e]);
} else {
respond(["error","unnamed_error",e.toSource()]);
}
http://git-wip-us.apache.org/repos/asf/couchdb/blob/32a11134/share/server/validate.js
----------------------------------------------------------------------
diff --git a/share/server/validate.js b/share/server/validate.js
index 76a1412..5b50e54 100644
--- a/share/server/validate.js
+++ b/share/server/validate.js
@@ -14,8 +14,11 @@ var Validate = {
validate : function(fun, ddoc, args) {
try {
fun.apply(ddoc, args);
- print("1");
+ respond(1);
} catch (error) {
+ if (error.name && error.stack) {
+ throw error;
+ }
respond(error);
}
}
http://git-wip-us.apache.org/repos/asf/couchdb/blob/32a11134/share/www/script/couch.js
----------------------------------------------------------------------
diff --git a/share/www/script/couch.js b/share/www/script/couch.js
index 86aaabf..d078d96 100644
--- a/share/www/script/couch.js
+++ b/share/www/script/couch.js
@@ -462,7 +462,8 @@ CouchDB.maybeThrowError = function(req) {
} catch (ParseError) {
var result = {error:"unknown", reason:req.responseText};
}
- throw result;
+
+ throw (new CouchError(result));
}
}
@@ -485,3 +486,13 @@ if (typeof window == 'undefined' || !window) {
CouchDB.inBrowser = true;
CouchDB.protocol = window.location.protocol + "//";
}
+
+// Turns an {error: ..., reason: ...} response into an Error instance
+function CouchError(error) {
+ var inst = new Error(error.reason);
+ inst.name = 'CouchError';
+ inst.error = error.error;
+ inst.reason = error.reason;
+ return inst;
+}
+CouchError.prototype.constructor = CouchError;
http://git-wip-us.apache.org/repos/asf/couchdb/blob/32a11134/src/couchdb/priv/couch_js/sm170.c
----------------------------------------------------------------------
diff --git a/src/couchdb/priv/couch_js/sm170.c b/src/couchdb/priv/couch_js/sm170.c
index 796c1d6..bb28870 100644
--- a/src/couchdb/priv/couch_js/sm170.c
+++ b/src/couchdb/priv/couch_js/sm170.c
@@ -113,6 +113,7 @@ req_status(JSContext* cx, JSObject* obj, jsval idval, jsval* rval)
static JSBool
+base_url(JSContext *cx, JSObject* obj, jsval idval, jsval* rval)
evalcx(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
JSString *str;
@@ -244,6 +245,7 @@ JSClass CouchHTTPClass = {
JSPropertySpec CouchHTTPProperties[] = {
{"status", 0, JSPROP_READONLY, req_status, NULL},
+ {"base_url", 0, JSPROP_READONLY | JSPROP_SHARED, base_url, NULL},
{0, 0, 0, 0, 0}
};
http://git-wip-us.apache.org/repos/asf/couchdb/blob/32a11134/src/couchdb/priv/couch_js/sm180.c
----------------------------------------------------------------------
diff --git a/src/couchdb/priv/couch_js/sm180.c b/src/couchdb/priv/couch_js/sm180.c
index 4d1bbf9..d7728a3 100644
--- a/src/couchdb/priv/couch_js/sm180.c
+++ b/src/couchdb/priv/couch_js/sm180.c
@@ -116,6 +116,7 @@ req_status(JSContext* cx, JSObject* obj, jsval idval, jsval* vp)
static JSBool
+base_url(JSContext *cx, JSObject* obj, jsid pid, jsval* vp)
evalcx(JSContext *cx, uintN argc, jsval* vp)
{
jsval* argv = JS_ARGV(cx, vp);
@@ -253,6 +254,7 @@ JSClass CouchHTTPClass = {
JSPropertySpec CouchHTTPProperties[] = {
{"status", 0, JSPROP_READONLY, req_status, NULL},
+ {"base_url", 0, JSPROP_READONLY | JSPROP_SHARED, base_url, NULL},
{0, 0, 0, 0, 0}
};
http://git-wip-us.apache.org/repos/asf/couchdb/blob/32a11134/src/couchdb/priv/couch_js/sm185.c
----------------------------------------------------------------------
diff --git a/src/couchdb/priv/couch_js/sm185.c b/src/couchdb/priv/couch_js/sm185.c
index 8c4e536..7757514 100644
--- a/src/couchdb/priv/couch_js/sm185.c
+++ b/src/couchdb/priv/couch_js/sm185.c
@@ -134,6 +134,7 @@ req_status(JSContext* cx, JSObject* obj, jsid pid, jsval* vp)
static JSBool
+base_url(JSContext *cx, JSObject* obj, jsid pid, jsval* vp)
evalcx(JSContext *cx, uintN argc, jsval* vp)
{
jsval* argv = JS_ARGV(cx, vp);
@@ -279,6 +280,7 @@ JSClass CouchHTTPClass = {
JSPropertySpec CouchHTTPProperties[] = {
{"status", 0, JSPROP_READONLY, req_status, NULL},
+ {"base_url", 0, JSPROP_READONLY | JSPROP_SHARED, base_url, NULL},
{0, 0, 0, 0, 0}
};
http://git-wip-us.apache.org/repos/asf/couchdb/blob/32a11134/src/couchdb/priv/couch_js/util.c
----------------------------------------------------------------------
diff --git a/src/couchdb/priv/couch_js/util.c b/src/couchdb/priv/couch_js/util.c
index 0b1e92a..b7bd3e4 100644
--- a/src/couchdb/priv/couch_js/util.c
+++ b/src/couchdb/priv/couch_js/util.c
@@ -227,9 +227,52 @@ couch_print(JSContext* cx, uintN argc, jsval* argv)
void
couch_error(JSContext* cx, const char* mesg, JSErrorReport* report)
{
+ jsval v, replace;
+ char* bytes;
+ JSObject* regexp, *stack;
+ jsval re_args[2];
+
if(!report || !JSREPORT_IS_WARNING(report->flags))
{
- fprintf(stderr, "[couchjs] %s\n", mesg);
+ fprintf(stderr, "%s\n", mesg);
+
+ // Print a stack trace, if available.
+ if (JSREPORT_IS_EXCEPTION(report->flags) &&
+ JS_GetPendingException(cx, &v))
+ {
+ // Clear the exception before an JS method calls or the result is
+ // infinite, recursive error report generation.
+ JS_ClearPendingException(cx);
+
+ // Use JS regexp to indent the stack trace.
+ // If the regexp can't be created, don't JS_ReportError since it is
+ // probably not productive to wind up here again.
+#ifdef SM185
+ if(JS_GetProperty(cx, JSVAL_TO_OBJECT(v), "stack", &v) &&
+ (regexp = JS_NewRegExpObjectNoStatics(
+ cx, "^(?=.)", 6, JSREG_GLOB | JSREG_MULTILINE)))
+#else
+ if(JS_GetProperty(cx, JSVAL_TO_OBJECT(v), "stack", &v) &&
+ (regexp = JS_NewRegExpObject(
+ cx, "^(?=.)", 6, JSREG_GLOB | JSREG_MULTILINE)))
+#endif
+ {
+ // Set up the arguments to ``String.replace()``
+ re_args[0] = OBJECT_TO_JSVAL(regexp);
+ re_args[1] = STRING_TO_JSVAL(JS_InternString(cx, "\t"));
+
+ // Perform the replacement
+ if(JS_ValueToObject(cx, v, &stack) &&
+ JS_GetProperty(cx, stack, "replace", &replace) &&
+ JS_CallFunctionValue(cx, stack, replace, 2, re_args, &v))
+ {
+ // Print the result
+ bytes = enc_string(cx, v, NULL);
+ fprintf(stderr, "Stacktrace:\n%s", bytes);
+ JS_free(cx, bytes);
+ }
+ }
+ }
}
}
http://git-wip-us.apache.org/repos/asf/couchdb/blob/32a11134/test/javascript/cli_runner.js
----------------------------------------------------------------------
diff --git a/test/javascript/cli_runner.js b/test/javascript/cli_runner.js
index 6683ede..d9d7fce 100644
--- a/test/javascript/cli_runner.js
+++ b/test/javascript/cli_runner.js
@@ -19,7 +19,8 @@ var console = {
function T(arg1, arg2) {
if(!arg1) {
- throw((arg2 ? arg2 : arg1).toString());
+ var result = (arg2 ? arg2 : arg1);
+ throw((result instanceof Error ? result : Error(result)));
}
}
@@ -28,9 +29,11 @@ function runTestConsole(num, name, func) {
func();
print("ok " + num + " " + name);
} catch(e) {
- msg = e.toString();
- msg = msg.replace(/\n/g, "\n ");
- print("not ok " + num + " " + name + " " + msg);
+ print("not ok " + num + " " + name);
+ print("# " + e.toSource());
+ if (e.stack) {
+ print("# Stacktrace:\n" + e.stack.replace(/^/gm, "\t"));
+ }
}
}
@@ -45,9 +48,5 @@ function runAllTestsConsole() {
}
};
-try {
- waitForSuccess(CouchDB.getVersion);
- runAllTestsConsole();
-} catch (e) {
- p("# " + e.toString());
-}
+waitForSuccess(CouchDB.getVersion);
+runAllTestsConsole();