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

Side by Side Diff: extensions/renderer/bindings/exception_handler_unittest.cc

Issue 2961103002: [Extensions Bindings] Add an ExceptionHandler class (Closed)
Patch Set: rebase Created 3 years, 5 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "extensions/renderer/bindings/exception_handler.h"
6
7 #include <string>
8
9 #include "base/bind.h"
10 #include "base/optional.h"
11 #include "base/strings/stringprintf.h"
12 #include "extensions/renderer/bindings/api_binding_test.h"
13 #include "extensions/renderer/bindings/api_binding_test_util.h"
14 #include "gin/converter.h"
15
16 namespace extensions {
17
18 namespace {
19
20 void PopulateError(base::Optional<std::string>* error_out,
21 v8::Local<v8::Context> context,
22 const std::string& error) {
23 *error_out = error;
24 }
25
26 void ThrowException(v8::Local<v8::Context> context,
27 const std::string& to_throw,
28 ExceptionHandler* handler) {
29 v8::Isolate* isolate = context->GetIsolate();
30 v8::TryCatch try_catch(isolate);
31 v8::Local<v8::Function> function = FunctionFromString(
32 context,
33 base::StringPrintf("(function() { throw %s; })", to_throw.c_str()));
34 ignore_result(function->Call(context, v8::Undefined(isolate), 0, nullptr));
35 ASSERT_TRUE(try_catch.HasCaught());
36 handler->HandleException(context, "handled", try_catch);
37 }
38
39 } // namespace
40
41 using ExceptionHandlerTest = APIBindingTest;
42
43 TEST_F(ExceptionHandlerTest, TestBasicHandling) {
44 v8::HandleScope handle_scope(isolate());
45 v8::Local<v8::Context> context = MainContext();
46
47 base::Optional<std::string> logged_error;
48 ExceptionHandler handler(base::Bind(&PopulateError, &logged_error),
49 base::Bind(&RunFunctionOnGlobalAndIgnoreResult));
50
51 ThrowException(context, "new Error('some error')", &handler);
52
53 ASSERT_TRUE(logged_error);
54 EXPECT_EQ("handled: Uncaught Error: some error", *logged_error);
55 }
56
57 TEST_F(ExceptionHandlerTest, PerContextHandlers) {
58 v8::HandleScope handle_scope(isolate());
59 v8::Local<v8::Context> context_a = MainContext();
60 v8::Local<v8::Context> context_b = AddContext();
61
62 base::Optional<std::string> logged_error;
63 ExceptionHandler handler(base::Bind(&PopulateError, &logged_error),
64 base::Bind(&RunFunctionOnGlobalAndIgnoreResult));
65
66 v8::Local<v8::Function> custom_handler = FunctionFromString(
67 context_a,
68 "(function(message, exception) {\n"
69 " this.loggedMessage = message;\n"
70 " this.loggedExceptionMessage = exception && exception.message;\n"
71 "})");
72
73 handler.SetHandlerForContext(context_a, custom_handler);
74 ThrowException(context_a, "new Error('context a error')", &handler);
75 EXPECT_FALSE(logged_error);
76 EXPECT_EQ("\"handled: Uncaught Error: context a error\"",
77 GetStringPropertyFromObject(context_a->Global(), context_a,
78 "loggedMessage"));
79 EXPECT_EQ("\"context a error\"",
80 GetStringPropertyFromObject(context_a->Global(), context_a,
81 "loggedExceptionMessage"));
82
83 ASSERT_TRUE(context_a->Global()
84 ->Set(context_a,
85 gin::StringToSymbol(isolate(), "loggedMessage"),
86 v8::Undefined(isolate()))
87 .ToChecked());
88 ASSERT_TRUE(
89 context_a->Global()
90 ->Set(context_a,
91 gin::StringToSymbol(isolate(), "loggedExceptionMessage"),
92 v8::Undefined(isolate()))
93 .ToChecked());
94
95 ThrowException(context_b, "new Error('context b error')", &handler);
96 ASSERT_TRUE(logged_error);
97 EXPECT_EQ("handled: Uncaught Error: context b error", *logged_error);
98 EXPECT_EQ("undefined", GetStringPropertyFromObject(
99 context_a->Global(), context_a, "loggedMessage"));
100 EXPECT_EQ("undefined",
101 GetStringPropertyFromObject(context_a->Global(), context_a,
102 "loggedExceptionMessage"));
103 }
104
105 TEST_F(ExceptionHandlerTest, ThrowingNonErrors) {
106 v8::HandleScope handle_scope(isolate());
107 v8::Local<v8::Context> context = MainContext();
108
109 base::Optional<std::string> logged_error;
110 ExceptionHandler handler(base::Bind(&PopulateError, &logged_error),
111 base::Bind(&RunFunctionOnGlobalAndIgnoreResult));
112
113 ThrowException(context, "'hello'", &handler);
114 ASSERT_TRUE(logged_error);
115 EXPECT_EQ("handled: Uncaught hello", *logged_error);
116 logged_error.reset();
117
118 ThrowException(context, "{ message: 'hello' }", &handler);
119 ASSERT_TRUE(logged_error);
120 EXPECT_EQ("handled: Uncaught #<Object>", *logged_error);
121 logged_error.reset();
122
123 ThrowException(context, "{ toString: function() { throw 'goodbye' } }",
124 &handler);
125 ASSERT_TRUE(logged_error);
126 EXPECT_EQ("handled: Uncaught [object Object]", *logged_error);
127
128 v8::Local<v8::Function> custom_handler =
129 FunctionFromString(context,
130 "(function(message, exception) {\n"
131 " this.loggedMessage = message;\n"
132 " this.loggedException = exception;\n"
133 "})");
134
135 handler.SetHandlerForContext(context, custom_handler);
136 ThrowException(context, "'hello'", &handler);
137 EXPECT_EQ(
138 "\"handled: Uncaught hello\"",
139 GetStringPropertyFromObject(context->Global(), context, "loggedMessage"));
140 EXPECT_EQ("\"hello\"", GetStringPropertyFromObject(context->Global(), context,
141 "loggedException"));
142 }
143
144 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698