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

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

Issue 2961103002: [Extensions Bindings] Add an ExceptionHandler class (Closed)
Patch Set: jbroman's 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 ExceptionHandlerPerContextData() {}
jbroman 2017/07/06 21:09:18 Is the constructor necessary? I thought it was imp
Devlin 2017/07/11 17:33:35 Removed.
23
24 v8::Global<v8::Function> custom_handler;
25 };
26
27 // TODO(devlin): Extract this to a utility method.
28 ExceptionHandlerPerContextData* GetContextData(v8::Local<v8::Context> context,
29 bool should_create) {
30 gin::PerContextData* per_context_data = gin::PerContextData::From(context);
31 if (!per_context_data)
32 return nullptr;
33 auto* data = static_cast<ExceptionHandlerPerContextData*>(
34 per_context_data->GetUserData(kExtensionExceptionHandlerPerContextKey));
35
36 if (!data && should_create) {
37 auto api_data = base::MakeUnique<ExceptionHandlerPerContextData>();
38 data = api_data.get();
39 per_context_data->SetUserData(kExtensionExceptionHandlerPerContextKey,
40 std::move(api_data));
41 }
42
43 return data;
44 }
45
46 } // namespace
47
48 ExceptionHandler::ExceptionHandler(
49 const binding::AddConsoleError& add_console_error,
50 const binding::RunJSFunction& run_js)
51 : add_console_error_(add_console_error), run_js_(run_js) {}
52 ExceptionHandler::~ExceptionHandler() {}
53
54 void ExceptionHandler::HandleException(v8::Local<v8::Context> context,
55 const std::string& message,
56 v8::TryCatch* try_catch) {
57 DCHECK(try_catch->HasCaught());
58
59 v8::Isolate* isolate = context->GetIsolate();
60 v8::HandleScope handle_scope(isolate);
61
62 v8::Local<v8::Message> v8_message = try_catch->Message();
63 std::string full_message =
64 !v8_message.IsEmpty()
65 ? base::StringPrintf("%s: %s", message.c_str(),
66 gin::V8ToString(v8_message->Get()).c_str())
67 : message;
68
69 v8::Local<v8::Function> handler = GetCustomHandler(context);
70 if (!handler.IsEmpty()) {
71 v8::Local<v8::Value> arguments[] = {
72 gin::StringToV8(isolate, full_message), try_catch->Exception(),
73 };
74 v8::TryCatch try_catch(isolate);
jbroman 2017/07/06 21:09:18 nit: Give this a separate name, to avoid shadowing
Devlin 2017/07/11 17:33:35 Done.
75 run_js_.Run(handler, context, arraysize(arguments), arguments);
76 } else {
77 add_console_error_.Run(context, full_message);
78 }
79
80 try_catch->Reset(); // Reset() to avoid handling the error more than once.
81 }
82
83 void ExceptionHandler::SetHandlerForContext(v8::Local<v8::Context> context,
84 v8::Local<v8::Function> handler) {
85 ExceptionHandlerPerContextData* data = GetContextData(context, true);
86 data->custom_handler =
87 v8::Global<v8::Function>(context->GetIsolate(), handler);
jbroman 2017/07/06 21:09:18 It's kind of implied by the lack of a null check h
jbroman 2017/07/06 21:09:18 slightly more concise to say "data->custom_handler
Devlin 2017/07/11 17:33:35 Done.
Devlin 2017/07/11 17:33:36 Done.
88 }
89
90 v8::Local<v8::Function> ExceptionHandler::GetCustomHandler(
91 v8::Local<v8::Context> context) {
92 ExceptionHandlerPerContextData* data = GetContextData(context, true);
jbroman 2017/07/06 21:09:18 true -> false
Devlin 2017/07/11 17:33:35 Whoops, thanks. Done.
93 return data ? data->custom_handler.Get(context->GetIsolate())
94 : v8::Local<v8::Function>();
95 }
96
97 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698