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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: extensions/renderer/bindings/exception_handler.cc
diff --git a/extensions/renderer/bindings/exception_handler.cc b/extensions/renderer/bindings/exception_handler.cc
new file mode 100644
index 0000000000000000000000000000000000000000..90e324473fb4983ee2802fd59e7a750c5f5f494f
--- /dev/null
+++ b/extensions/renderer/bindings/exception_handler.cc
@@ -0,0 +1,97 @@
+// 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 "base/logging.h"
+#include "base/memory/ptr_util.h"
+#include "base/strings/stringprintf.h"
+#include "base/supports_user_data.h"
+#include "gin/converter.h"
+#include "gin/per_context_data.h"
+
+namespace extensions {
+
+namespace {
+
+const char kExtensionExceptionHandlerPerContextKey[] =
+ "extension_exception_handler";
+
+struct ExceptionHandlerPerContextData : public base::SupportsUserData::Data {
+ 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.
+
+ v8::Global<v8::Function> custom_handler;
+};
+
+// TODO(devlin): Extract this to a utility method.
+ExceptionHandlerPerContextData* GetContextData(v8::Local<v8::Context> context,
+ bool should_create) {
+ gin::PerContextData* per_context_data = gin::PerContextData::From(context);
+ if (!per_context_data)
+ return nullptr;
+ auto* data = static_cast<ExceptionHandlerPerContextData*>(
+ per_context_data->GetUserData(kExtensionExceptionHandlerPerContextKey));
+
+ if (!data && should_create) {
+ auto api_data = base::MakeUnique<ExceptionHandlerPerContextData>();
+ data = api_data.get();
+ per_context_data->SetUserData(kExtensionExceptionHandlerPerContextKey,
+ std::move(api_data));
+ }
+
+ return data;
+}
+
+} // namespace
+
+ExceptionHandler::ExceptionHandler(
+ const binding::AddConsoleError& add_console_error,
+ const binding::RunJSFunction& run_js)
+ : add_console_error_(add_console_error), run_js_(run_js) {}
+ExceptionHandler::~ExceptionHandler() {}
+
+void ExceptionHandler::HandleException(v8::Local<v8::Context> context,
+ const std::string& message,
+ v8::TryCatch* try_catch) {
+ DCHECK(try_catch->HasCaught());
+
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
+
+ v8::Local<v8::Message> v8_message = try_catch->Message();
+ std::string full_message =
+ !v8_message.IsEmpty()
+ ? base::StringPrintf("%s: %s", message.c_str(),
+ gin::V8ToString(v8_message->Get()).c_str())
+ : message;
+
+ v8::Local<v8::Function> handler = GetCustomHandler(context);
+ if (!handler.IsEmpty()) {
+ v8::Local<v8::Value> arguments[] = {
+ gin::StringToV8(isolate, full_message), try_catch->Exception(),
+ };
+ 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.
+ run_js_.Run(handler, context, arraysize(arguments), arguments);
+ } else {
+ add_console_error_.Run(context, full_message);
+ }
+
+ try_catch->Reset(); // Reset() to avoid handling the error more than once.
+}
+
+void ExceptionHandler::SetHandlerForContext(v8::Local<v8::Context> context,
+ v8::Local<v8::Function> handler) {
+ ExceptionHandlerPerContextData* data = GetContextData(context, true);
+ data->custom_handler =
+ 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.
+}
+
+v8::Local<v8::Function> ExceptionHandler::GetCustomHandler(
+ v8::Local<v8::Context> context) {
+ ExceptionHandlerPerContextData* data = GetContextData(context, true);
jbroman 2017/07/06 21:09:18 true -> false
Devlin 2017/07/11 17:33:35 Whoops, thanks. Done.
+ return data ? data->custom_handler.Get(context->GetIsolate())
+ : v8::Local<v8::Function>();
+}
+
+} // namespace extensions

Powered by Google App Engine
This is Rietveld 408576698