Added API call to get the stack trace for an exception
authorchristian.plesner.hansen@gmail.com <christian.plesner.hansen@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 17 Aug 2009 13:34:41 +0000 (13:34 +0000)
committerchristian.plesner.hansen@gmail.com <christian.plesner.hansen@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 17 Aug 2009 13:34:41 +0000 (13:34 +0000)
Added TryCatch::StackTrace that gets the stack trace for the thrown
exception.

Review URL: http://codereview.chromium.org/171042

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2698 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

include/v8.h
src/api.cc
test/cctest/test-api.cc

index 77223a0..a0cc4ea 100644 (file)
@@ -2290,6 +2290,12 @@ class V8EXPORT TryCatch {
   Local<Value> Exception() const;
 
   /**
+   * Returns the .stack property of the thrown object.  If no .stack
+   * property is present an empty handle is returned.
+   */
+  Local<Value> StackTrace() const;
+
+  /**
    * Returns the message associated with this exception.  If there is
    * no message associated an empty handle is returned.
    *
index 2f7de08..c606821 100644 (file)
@@ -1219,6 +1219,22 @@ v8::Local<Value> v8::TryCatch::Exception() const {
 }
 
 
+v8::Local<Value> v8::TryCatch::StackTrace() const {
+  if (HasCaught()) {
+    i::Object* raw_obj = reinterpret_cast<i::Object*>(exception_);
+    if (!raw_obj->IsJSObject()) return v8::Local<Value>();
+    v8::HandleScope scope;
+    i::Handle<i::JSObject> obj(i::JSObject::cast(raw_obj));
+    i::Handle<i::String> name = i::Factory::LookupAsciiSymbol("stack");
+    if (!obj->HasProperty(*name))
+      return v8::Local<Value>();
+    return scope.Close(v8::Utils::ToLocal(i::GetProperty(obj, name)));
+  } else {
+    return v8::Local<Value>();
+  }
+}
+
+
 v8::Local<v8::Message> v8::TryCatch::Message() const {
   if (HasCaught() && message_ != i::Smi::FromInt(0)) {
     i::Object* message = reinterpret_cast<i::Object*>(message_);
index e0c9f3e..e1caba3 100644 (file)
@@ -7753,3 +7753,16 @@ THREADED_TEST(ScriptContextDependence) {
   CHECK_EQ(dep->Run()->Int32Value(), 100);
   CHECK_EQ(indep->Run()->Int32Value(), 101);
 }
+
+THREADED_TEST(StackTrace) {
+  v8::HandleScope scope;
+  LocalContext context;
+  v8::TryCatch try_catch;
+  const char *source = "function foo() { FAIL.FAIL; }; foo();";
+  v8::Handle<v8::String> src = v8::String::New(source);
+  v8::Handle<v8::String> origin = v8::String::New("stack-trace-test");
+  v8::Script::New(src, origin)->Run();
+  CHECK(try_catch.HasCaught());
+  v8::String::Utf8Value stack(try_catch.StackTrace());
+  CHECK(strstr(*stack, "at foo (stack-trace-test") != NULL);
+}