Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(68)

Unified Diff: extensions/renderer/bindings/exception_handler_unittest.cc

Issue 2961103002: [Extensions Bindings] Add an ExceptionHandler class (Closed)
Patch Set: rebase Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: extensions/renderer/bindings/exception_handler_unittest.cc
diff --git a/extensions/renderer/bindings/exception_handler_unittest.cc b/extensions/renderer/bindings/exception_handler_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..cc0a4ecfd994ebe68e0de51329bd8ca88a81213a
--- /dev/null
+++ b/extensions/renderer/bindings/exception_handler_unittest.cc
@@ -0,0 +1,144 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "extensions/renderer/bindings/exception_handler.h"
+
+#include <string>
+
+#include "base/bind.h"
+#include "base/optional.h"
+#include "base/strings/stringprintf.h"
+#include "extensions/renderer/bindings/api_binding_test.h"
+#include "extensions/renderer/bindings/api_binding_test_util.h"
+#include "gin/converter.h"
+
+namespace extensions {
+
+namespace {
+
+void PopulateError(base::Optional<std::string>* error_out,
+ v8::Local<v8::Context> context,
+ const std::string& error) {
+ *error_out = error;
+}
+
+void ThrowException(v8::Local<v8::Context> context,
+ const std::string& to_throw,
+ ExceptionHandler* handler) {
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::TryCatch try_catch(isolate);
+ v8::Local<v8::Function> function = FunctionFromString(
+ context,
+ base::StringPrintf("(function() { throw %s; })", to_throw.c_str()));
+ ignore_result(function->Call(context, v8::Undefined(isolate), 0, nullptr));
+ ASSERT_TRUE(try_catch.HasCaught());
+ handler->HandleException(context, "handled", try_catch);
+}
+
+} // namespace
+
+using ExceptionHandlerTest = APIBindingTest;
+
+TEST_F(ExceptionHandlerTest, TestBasicHandling) {
+ v8::HandleScope handle_scope(isolate());
+ v8::Local<v8::Context> context = MainContext();
+
+ base::Optional<std::string> logged_error;
+ ExceptionHandler handler(base::Bind(&PopulateError, &logged_error),
+ base::Bind(&RunFunctionOnGlobalAndIgnoreResult));
+
+ ThrowException(context, "new Error('some error')", &handler);
+
+ ASSERT_TRUE(logged_error);
+ EXPECT_EQ("handled: Uncaught Error: some error", *logged_error);
+}
+
+TEST_F(ExceptionHandlerTest, PerContextHandlers) {
+ v8::HandleScope handle_scope(isolate());
+ v8::Local<v8::Context> context_a = MainContext();
+ v8::Local<v8::Context> context_b = AddContext();
+
+ base::Optional<std::string> logged_error;
+ ExceptionHandler handler(base::Bind(&PopulateError, &logged_error),
+ base::Bind(&RunFunctionOnGlobalAndIgnoreResult));
+
+ v8::Local<v8::Function> custom_handler = FunctionFromString(
+ context_a,
+ "(function(message, exception) {\n"
+ " this.loggedMessage = message;\n"
+ " this.loggedExceptionMessage = exception && exception.message;\n"
+ "})");
+
+ handler.SetHandlerForContext(context_a, custom_handler);
+ ThrowException(context_a, "new Error('context a error')", &handler);
+ EXPECT_FALSE(logged_error);
+ EXPECT_EQ("\"handled: Uncaught Error: context a error\"",
+ GetStringPropertyFromObject(context_a->Global(), context_a,
+ "loggedMessage"));
+ EXPECT_EQ("\"context a error\"",
+ GetStringPropertyFromObject(context_a->Global(), context_a,
+ "loggedExceptionMessage"));
+
+ ASSERT_TRUE(context_a->Global()
+ ->Set(context_a,
+ gin::StringToSymbol(isolate(), "loggedMessage"),
+ v8::Undefined(isolate()))
+ .ToChecked());
+ ASSERT_TRUE(
+ context_a->Global()
+ ->Set(context_a,
+ gin::StringToSymbol(isolate(), "loggedExceptionMessage"),
+ v8::Undefined(isolate()))
+ .ToChecked());
+
+ ThrowException(context_b, "new Error('context b error')", &handler);
+ ASSERT_TRUE(logged_error);
+ EXPECT_EQ("handled: Uncaught Error: context b error", *logged_error);
+ EXPECT_EQ("undefined", GetStringPropertyFromObject(
+ context_a->Global(), context_a, "loggedMessage"));
+ EXPECT_EQ("undefined",
+ GetStringPropertyFromObject(context_a->Global(), context_a,
+ "loggedExceptionMessage"));
+}
+
+TEST_F(ExceptionHandlerTest, ThrowingNonErrors) {
+ v8::HandleScope handle_scope(isolate());
+ v8::Local<v8::Context> context = MainContext();
+
+ base::Optional<std::string> logged_error;
+ ExceptionHandler handler(base::Bind(&PopulateError, &logged_error),
+ base::Bind(&RunFunctionOnGlobalAndIgnoreResult));
+
+ ThrowException(context, "'hello'", &handler);
+ ASSERT_TRUE(logged_error);
+ EXPECT_EQ("handled: Uncaught hello", *logged_error);
+ logged_error.reset();
+
+ ThrowException(context, "{ message: 'hello' }", &handler);
+ ASSERT_TRUE(logged_error);
+ EXPECT_EQ("handled: Uncaught #<Object>", *logged_error);
+ logged_error.reset();
+
+ ThrowException(context, "{ toString: function() { throw 'goodbye' } }",
+ &handler);
+ ASSERT_TRUE(logged_error);
+ EXPECT_EQ("handled: Uncaught [object Object]", *logged_error);
+
+ v8::Local<v8::Function> custom_handler =
+ FunctionFromString(context,
+ "(function(message, exception) {\n"
+ " this.loggedMessage = message;\n"
+ " this.loggedException = exception;\n"
+ "})");
+
+ handler.SetHandlerForContext(context, custom_handler);
+ ThrowException(context, "'hello'", &handler);
+ EXPECT_EQ(
+ "\"handled: Uncaught hello\"",
+ GetStringPropertyFromObject(context->Global(), context, "loggedMessage"));
+ EXPECT_EQ("\"hello\"", GetStringPropertyFromObject(context->Global(), context,
+ "loggedException"));
+}
+
+} // namespace extensions

Powered by Google App Engine
This is Rietveld 408576698