}
// Save the message for reporting if the the exception remains uncaught.
+ thread_local_.has_pending_message_ = report_exception;
thread_local_.pending_message_ = message;
if (!message_obj.is_null()) {
thread_local_.pending_message_obj_ = *message_obj;
context()->mark_out_of_memory();
} else {
Handle<Object> exception(pending_exception());
- if (thread_local_.external_caught_exception_) {
+ bool external_caught = thread_local_.external_caught_exception_;
+ thread_local_.external_caught_exception_ = false;
+ if (external_caught) {
thread_local_.try_catch_handler_->exception_ =
thread_local_.pending_exception_;
if (!thread_local_.pending_message_obj_->IsTheHole()) {
try_catch_handler()->message_ = thread_local_.pending_message_obj_;
}
- } else if (thread_local_.pending_message_ != NULL) {
- MessageHandler::ReportMessage(thread_local_.pending_message_);
- } else if (!thread_local_.pending_message_obj_->IsTheHole()) {
- Handle<Object> message_obj(thread_local_.pending_message_obj_);
- if (thread_local_.pending_message_script_ != NULL) {
- Handle<Script> script(thread_local_.pending_message_script_);
- int start_pos = thread_local_.pending_message_start_pos_;
- int end_pos = thread_local_.pending_message_end_pos_;
- MessageLocation location(script, start_pos, end_pos);
- MessageHandler::ReportMessage(&location, message_obj);
- } else {
- MessageHandler::ReportMessage(NULL, message_obj);
+ }
+ if (thread_local_.has_pending_message_) {
+ thread_local_.has_pending_message_ = false;
+ if (thread_local_.pending_message_ != NULL) {
+ MessageHandler::ReportMessage(thread_local_.pending_message_);
+ } else if (!thread_local_.pending_message_obj_->IsTheHole()) {
+ Handle<Object> message_obj(thread_local_.pending_message_obj_);
+ if (thread_local_.pending_message_script_ != NULL) {
+ Handle<Script> script(thread_local_.pending_message_script_);
+ int start_pos = thread_local_.pending_message_start_pos_;
+ int end_pos = thread_local_.pending_message_end_pos_;
+ MessageLocation location(script, start_pos, end_pos);
+ MessageHandler::ReportMessage(&location, message_obj);
+ } else {
+ MessageHandler::ReportMessage(NULL, message_obj);
+ }
}
}
+ thread_local_.external_caught_exception_ = external_caught;
set_pending_exception(*exception);
}
clear_pending_message();
// lookups.
Context* context_;
Object* pending_exception_;
+ bool has_pending_message_;
const char* pending_message_;
Object* pending_message_obj_;
Script* pending_message_script_;
}
static void clear_pending_message() {
thread_local_.catcher_ = NULL;
+ thread_local_.has_pending_message_ = false;
thread_local_.pending_message_ = NULL;
thread_local_.pending_message_obj_ = Heap::the_hole_value();
thread_local_.pending_message_script_ = NULL;
}
+THREADED_TEST(APIThrowTryCatch) {
+ v8::HandleScope scope;
+ Local<ObjectTemplate> templ = ObjectTemplate::New();
+ templ->Set(v8_str("ThrowFromC"),
+ v8::FunctionTemplate::New(ThrowFromC));
+ LocalContext context(0, templ);
+ v8::TryCatch try_catch;
+ CompileRun("ThrowFromC();");
+ CHECK(try_catch.HasCaught());
+}
+
+
+static void receive_message(v8::Handle<v8::Message> message,
+ v8::Handle<v8::Value> data) {
+ message_received = true;
+}
+
+
+TEST(APIThrowMessage) {
+ message_received = false;
+ v8::HandleScope scope;
+ v8::V8::AddMessageListener(receive_message);
+ Local<ObjectTemplate> templ = ObjectTemplate::New();
+ templ->Set(v8_str("ThrowFromC"),
+ v8::FunctionTemplate::New(ThrowFromC));
+ LocalContext context(0, templ);
+ CompileRun("ThrowFromC();");
+ CHECK(message_received);
+ v8::V8::RemoveMessageListeners(check_message);
+}
+
+
+TEST(APIThrowMessageAndVerboseTryCatch) {
+ message_received = false;
+ v8::HandleScope scope;
+ v8::V8::AddMessageListener(receive_message);
+ Local<ObjectTemplate> templ = ObjectTemplate::New();
+ templ->Set(v8_str("ThrowFromC"),
+ v8::FunctionTemplate::New(ThrowFromC));
+ LocalContext context(0, templ);
+ v8::TryCatch try_catch;
+ try_catch.SetVerbose(true);
+ CompileRun("ThrowFromC();");
+ CHECK(try_catch.HasCaught());
+ CHECK(message_received);
+ v8::V8::RemoveMessageListeners(check_message);
+}
+
+
THREADED_TEST(ExternalScriptException) {
v8::HandleScope scope;
Local<ObjectTemplate> templ = ObjectTemplate::New();