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

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

Issue 2961103002: [Extensions Bindings] Add an ExceptionHandler class (Closed)
Patch Set: rebase + nits 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 "base/logging.h"
8 #include "base/memory/ptr_util.h"
9 #include "base/strings/stringprintf.h"
10 #include "base/supports_user_data.h"
11 #include "gin/converter.h"
12 #include "gin/per_context_data.h"
13
14 namespace extensions {
15
16 namespace {
17
18 const char kExtensionExceptionHandlerPerContextKey[] =
19 "extension_exception_handler";
20
21 struct ExceptionHandlerPerContextData : public base::SupportsUserData::Data {
22 v8::Global<v8::Function> custom_handler;
23 };
24
25 // TODO(devlin): Extract this to a utility method.
26 ExceptionHandlerPerContextData* GetContextData(v8::Local<v8::Context> context,
27 bool should_create) {
28 gin::PerContextData* per_context_data = gin::PerContextData::From(context);
29 if (!per_context_data)
30 return nullptr;
31 auto* data = static_cast<ExceptionHandlerPerContextData*>(
32 per_context_data->GetUserData(kExtensionExceptionHandlerPerContextKey));
33
34 if (!data && should_create) {
35 auto api_data = base::MakeUnique<ExceptionHandlerPerContextData>();
36 data = api_data.get();
37 per_context_data->SetUserData(kExtensionExceptionHandlerPerContextKey,
38 std::move(api_data));
39 }
40
41 return data;
42 }
43
44 } // namespace
45
46 ExceptionHandler::ExceptionHandler(
47 const binding::AddConsoleError& add_console_error,
48 const binding::RunJSFunction& run_js)
49 : add_console_error_(add_console_error), run_js_(run_js) {}
50 ExceptionHandler::~ExceptionHandler() {}
51
52 void ExceptionHandler::HandleException(v8::Local<v8::Context> context,
53 const std::string& message,
54 v8::TryCatch* try_catch) {
55 DCHECK(try_catch->HasCaught());
56
57 v8::Isolate* isolate = context->GetIsolate();
58 v8::HandleScope handle_scope(isolate);
59
60 v8::Local<v8::Message> v8_message = try_catch->Message();
61 std::string full_message =
62 !v8_message.IsEmpty()
63 ? base::StringPrintf("%s: %s", message.c_str(),
64 gin::V8ToString(v8_message->Get()).c_str())
65 : message;
66
67 v8::Local<v8::Function> handler = GetCustomHandler(context);
68 if (!handler.IsEmpty()) {
69 v8::Local<v8::Value> arguments[] = {
70 gin::StringToV8(isolate, full_message), try_catch->Exception(),
71 };
72 v8::TryCatch handler_try_catch(isolate);
73 run_js_.Run(handler, context, arraysize(arguments), arguments);
74 } else {
75 add_console_error_.Run(context, full_message);
76 }
77
78 try_catch->Reset(); // Reset() to avoid handling the error more than once.
79 }
80
81 void ExceptionHandler::SetHandlerForContext(v8::Local<v8::Context> context,
82 v8::Local<v8::Function> handler) {
83 ExceptionHandlerPerContextData* data = GetContextData(context, true);
84 DCHECK(data);
85 data->custom_handler.Reset(context->GetIsolate(), handler);
86 }
87
88 v8::Local<v8::Function> ExceptionHandler::GetCustomHandler(
89 v8::Local<v8::Context> context) {
90 ExceptionHandlerPerContextData* data = GetContextData(context, false);
91 return data ? data->custom_handler.Get(context->GetIsolate())
92 : v8::Local<v8::Function>();
93 }
94
95 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/renderer/bindings/exception_handler.h ('k') | extensions/renderer/bindings/exception_handler_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698