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

Side by Side Diff: extensions/renderer/api_last_error.cc

Issue 2657613005: [Extensions Bindings] Add chrome.runtime.lastError support (Closed)
Patch Set: . Created 3 years, 10 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/api_last_error.h"
6
7 #include "gin/converter.h"
8 #include "gin/handle.h"
9 #include "gin/object_template_builder.h"
10 #include "gin/wrappable.h"
11
12 namespace extensions {
13
14 namespace {
15
16 const char kLastErrorProperty[] = "lastError";
17
18 class LastErrorObject final : public gin::Wrappable<LastErrorObject> {
19 public:
20 explicit LastErrorObject(const std::string& error) : error_(error) {}
21
22 static gin::WrapperInfo kWrapperInfo;
23
24 // gin::Wrappable:
25 gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
26 v8::Isolate* isolate) override {
27 DCHECK(isolate);
28 return Wrappable<LastErrorObject>::GetObjectTemplateBuilder(isolate)
29 .SetProperty("message", &LastErrorObject::GetLastError);
30 }
31
32 void Reset(const std::string& error) {
33 error_ = error;
34 accessed_ = false;
35 }
36
37 const std::string& error() const { return error_; }
38 bool accessed() const { return accessed_; }
39
40 private:
41 std::string GetLastError() {
42 accessed_ = true;
43 return error_;
44 }
45
46 std::string error_;
47 bool accessed_ = false;
48
49 DISALLOW_COPY_AND_ASSIGN(LastErrorObject);
50 };
51
52 gin::WrapperInfo LastErrorObject::kWrapperInfo = {gin::kEmbedderNativeGin};
53
54 } // namespace
55
56 APILastError::APILastError(const GetParent& get_parent)
57 : get_parent_(get_parent) {}
58 APILastError::APILastError(APILastError&& other) = default;
59 APILastError::~APILastError() = default;
60
61 void APILastError::SetError(v8::Local<v8::Context> context,
62 const std::string& error) {
63 v8::Isolate* isolate = context->GetIsolate();
64 DCHECK(isolate);
65 v8::HandleScope handle_scope(isolate);
66 v8::Local<v8::Object> parent = get_parent_.Run(context);
67 if (parent.IsEmpty())
68 return;
69 v8::Local<v8::String> key = gin::StringToSymbol(isolate, kLastErrorProperty);
70 v8::MaybeLocal<v8::Value> maybe_error = parent->Get(context, key);
71 v8::Local<v8::Value> local_error;
72 if (!maybe_error.ToLocal(&local_error))
73 return;
74
75 if (!local_error->IsUndefined()) {
76 // There may be an existing last error to overwrite.
77 LastErrorObject* last_error = nullptr;
78 if (!gin::Converter<LastErrorObject*>::FromV8(context->GetIsolate(),
79 local_error, &last_error)) {
80 // If it's not a real lastError (e.g. if a script manually set it), don't
81 // do anything.
82 return;
83 }
84 last_error->Reset(error);
85 } else {
86 DCHECK(context->GetIsolate());
87 v8::Local<v8::Value> last_error =
88 gin::CreateHandle(context->GetIsolate(), new LastErrorObject(error))
89 .ToV8();
90 DCHECK(!last_error.IsEmpty());
91 // This Set() can fail, but there's nothing else to do if it does.
92 ignore_result(parent->Set(
93 context, gin::StringToSymbol(isolate, kLastErrorProperty), last_error));
94 }
95 }
96
97 void APILastError::ClearError(v8::Local<v8::Context> context,
98 bool report_if_unchecked) {
99 v8::Isolate* isolate = context->GetIsolate();
100 v8::HandleScope handle_scope(isolate);
101 v8::Local<v8::Object> parent = get_parent_.Run(context);
102 if (parent.IsEmpty())
103 return;
104 v8::Local<v8::String> key = gin::StringToSymbol(isolate, kLastErrorProperty);
105 v8::MaybeLocal<v8::Value> maybe_error = parent->Get(context, key);
106 v8::Local<v8::Value> local_error;
107 if (!maybe_error.ToLocal(&local_error))
108 return;
109 LastErrorObject* last_error = nullptr;
110 if (!gin::Converter<LastErrorObject*>::FromV8(context->GetIsolate(),
111 local_error, &last_error)) {
112 return;
113 }
114
115 if (report_if_unchecked && !last_error->accessed()) {
116 isolate->ThrowException(
117 v8::Exception::Error(gin::StringToV8(isolate, last_error->error())));
118 }
119
120 parent->Delete(context, key);
jbroman 2017/01/30 23:08:34 Warning: v8::Object::Delete can throw an exception
Devlin 2017/01/31 17:15:00 What should we do with the result? Similar to lin
jbroman 2017/02/06 18:31:26 I'm not sure. We could: - let it be/rethrow (but w
Devlin 2017/02/06 20:28:22 As discussed offline, we'll catch the error (verbo
121 }
122
123 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698