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

Side by Side Diff: extensions/browser/extension_error.cc

Issue 22938005: Add ErrorConsole UI for Extension Install Warnings (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@dc_ec_install_warnings
Patch Set: Created 7 years, 4 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
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "extensions/browser/extension_error.h" 5 #include "extensions/browser/extension_error.h"
6 6
7 #include "base/json/json_reader.h" 7 #include "base/json/json_reader.h"
8 #include "base/strings/string_number_conversions.h" 8 #include "base/strings/string_number_conversions.h"
9 #include "base/strings/utf_string_conversions.h" 9 #include "base/strings/utf_string_conversions.h"
10 #include "base/values.h" 10 #include "base/values.h"
11 #include "extensions/common/constants.h" 11 #include "extensions/common/constants.h"
12 #include "url/gurl.h" 12 #include "url/gurl.h"
13 13
14 using base::string16; 14 using base::string16;
15 using base::DictionaryValue;
15 16
16 namespace extensions { 17 namespace extensions {
17 18
18 namespace { 19 namespace {
19 20
21 const char kTypeKey[] = "type";
22 const char kSourceKey[] = "source";
23 const char kMessageKey[] = "message";
24 const char kExtensionIdKey[] = "extensionId";
25 const char kFromIncognitoKey[] = "fromIncognito";
26 const char kManifestKeyKey[] = "manifestKey";
27 const char kManifestSpecificKey[] = "manifestSpecific";
28 const char kLevelKey[] = "level";
20 const char kLineNumberKey[] = "lineNumber"; 29 const char kLineNumberKey[] = "lineNumber";
21 const char kColumnNumberKey[] = "columnNumber"; 30 const char kColumnNumberKey[] = "columnNumber";
22 const char kURLKey[] = "url"; 31 const char kURLKey[] = "url";
23 const char kFunctionNameKey[] = "functionName"; 32 const char kFunctionNameKey[] = "functionName";
24 const char kExecutionContextURLKey[] = "executionContextURL"; 33 const char kExecutionContextURLKey[] = "executionContextURL";
25 const char kStackTraceKey[] = "stackTrace"; 34 const char kStackTraceKey[] = "stackTrace";
26 35
27 // Try to retrieve an extension ID from a |url|. On success, returns true and 36 // Try to retrieve an extension ID from a |url|. On success, returns true and
28 // populates |extension_id| with the ID. On failure, returns false and leaves 37 // populates |extension_id| with the ID. On failure, returns false and leaves
29 // extension_id untouched. 38 // extension_id untouched.
30 bool GetExtensionIDFromGURL(const GURL& url, std::string* extension_id) { 39 bool GetExtensionIdFromGURL(const GURL& url, std::string* extension_id) {
31 if (url.SchemeIs(kExtensionScheme)) { 40 if (url.SchemeIs(kExtensionScheme)) {
32 *extension_id = url.host(); 41 *extension_id = url.host();
33 return true; 42 return true;
34 } 43 }
35 return false; 44 return false;
36 } 45 }
37 46
38 } // namespace 47 } // namespace
39 48
40 ExtensionError::ExtensionError(Type type, 49 ExtensionError::ExtensionError(Type type,
41 const std::string& extension_id, 50 const std::string& extension_id,
42 bool from_incognito, 51 bool from_incognito,
43 const string16& source, 52 const string16& source,
44 const string16& message) 53 const string16& message)
45 : type_(type), 54 : type_(type),
46 extension_id_(extension_id), 55 extension_id_(extension_id),
47 from_incognito_(from_incognito), 56 from_incognito_(from_incognito),
48 source_(source), 57 source_(source),
49 message_(message) { 58 message_(message) {
50 } 59 }
51 60
52 ExtensionError::~ExtensionError() { 61 ExtensionError::~ExtensionError() {
53 } 62 }
54 63
64 scoped_ptr<DictionaryValue> ExtensionError::ToValue() const {
65 scoped_ptr<DictionaryValue> value(new DictionaryValue);
66 value->SetInteger(kTypeKey, static_cast<int>(type_));
67 value->SetString(kExtensionIdKey, extension_id_);
68 value->SetBoolean(kFromIncognitoKey, from_incognito_);
69 value->SetString(kSourceKey, source_);
70 value->SetString(kMessageKey, message_);
71
72 return value.Pass();
73 }
74
55 std::string ExtensionError::PrintForTest() const { 75 std::string ExtensionError::PrintForTest() const {
56 return std::string("Extension Error:") + 76 return std::string("Extension Error:") +
57 "\n OTR: " + std::string(from_incognito_ ? "true" : "false") + 77 "\n OTR: " + std::string(from_incognito_ ? "true" : "false") +
58 "\n Source: " + base::UTF16ToUTF8(source_) + 78 "\n Source: " + base::UTF16ToUTF8(source_) +
59 "\n Message: " + base::UTF16ToUTF8(message_) + 79 "\n Message: " + base::UTF16ToUTF8(message_) +
60 "\n ID: " + extension_id_; 80 "\n ID: " + extension_id_;
61 } 81 }
62 82
83 bool ExtensionError::IsEqual(const ExtensionError* rhs) const {
84 return type_ == rhs->type_ &&
85 extension_id_ == rhs->extension_id_ &&
86 source_ == rhs->source_ &&
87 message_ == rhs->message_ &&
88 IsEqualImpl(rhs);
89 }
90
63 ManifestParsingError::ManifestParsingError(const std::string& extension_id, 91 ManifestParsingError::ManifestParsingError(const std::string& extension_id,
64 const string16& message) 92 const string16& message,
93 const string16& manifest_key,
94 const string16& manifest_specific)
65 : ExtensionError(ExtensionError::MANIFEST_PARSING_ERROR, 95 : ExtensionError(ExtensionError::MANIFEST_PARSING_ERROR,
66 extension_id, 96 extension_id,
67 false, // extensions can't be installed while incognito. 97 false, // extensions can't be installed while incognito.
68 base::FilePath(kManifestFilename).AsUTF16Unsafe(), 98 base::FilePath(kManifestFilename).AsUTF16Unsafe(),
69 message) { 99 message),
100 manifest_key_(manifest_key),
101 manifest_specific_(manifest_specific) {
70 } 102 }
71 103
72 ManifestParsingError::~ManifestParsingError() { 104 ManifestParsingError::~ManifestParsingError() {
73 } 105 }
74 106
107 scoped_ptr<DictionaryValue> ManifestParsingError::ToValue() const {
108 scoped_ptr<DictionaryValue> value = ExtensionError::ToValue();
109 // All manifest errors are warnings - if it was a fatal error, we wouldn't
110 // get far enough to add an error for the extension.
111 value->SetInteger(kLevelKey, logging::LOG_WARNING);
112 if (!manifest_key_.empty())
113 value->SetString(kManifestKeyKey, manifest_key_);
114 if (!manifest_specific_.empty())
115 value->SetString(kManifestSpecificKey, manifest_specific_);
116 return value.Pass();
117 }
118
75 std::string ManifestParsingError::PrintForTest() const { 119 std::string ManifestParsingError::PrintForTest() const {
76 return ExtensionError::PrintForTest() + 120 return ExtensionError::PrintForTest() +
77 "\n Type: ManifestParsingError"; 121 "\n Type: ManifestParsingError";
78 } 122 }
79 123
124 bool ManifestParsingError::IsEqualImpl(const ExtensionError* rhs) const {
125 // If two manifest errors have the same extension id and message (which are
126 // both checked in ExtensionError::IsEqual), then they are equal.
127 return true;
128 }
129
80 JavascriptRuntimeError::StackFrame::StackFrame() : line_number(-1), 130 JavascriptRuntimeError::StackFrame::StackFrame() : line_number(-1),
81 column_number(-1) { 131 column_number(-1) {
82 } 132 }
83 133
84 JavascriptRuntimeError::StackFrame::StackFrame(size_t frame_line, 134 JavascriptRuntimeError::StackFrame::StackFrame(size_t frame_line,
85 size_t frame_column, 135 size_t frame_column,
86 const string16& frame_url, 136 const string16& frame_url,
87 const string16& frame_function) 137 const string16& frame_function)
88 : line_number(frame_line), 138 : line_number(frame_line),
89 column_number(frame_column), 139 column_number(frame_column),
90 url(frame_url), 140 url(frame_url),
91 function(frame_function) { 141 function(frame_function) {
92 } 142 }
93 143
94 JavascriptRuntimeError::StackFrame::~StackFrame() { 144 JavascriptRuntimeError::StackFrame::~StackFrame() {
95 } 145 }
96 146
147 bool JavascriptRuntimeError::StackFrame::operator==(
148 const JavascriptRuntimeError::StackFrame& rhs) const {
149 return line_number == rhs.line_number &&
150 column_number == rhs.column_number &&
151 url == rhs.url &&
152 function == rhs.function;
153 }
97 JavascriptRuntimeError::JavascriptRuntimeError(bool from_incognito, 154 JavascriptRuntimeError::JavascriptRuntimeError(bool from_incognito,
98 const string16& source, 155 const string16& source,
99 const string16& message, 156 const string16& message,
100 logging::LogSeverity level, 157 logging::LogSeverity level,
101 const string16& details) 158 const string16& details)
102 : ExtensionError(ExtensionError::JAVASCRIPT_RUNTIME_ERROR, 159 : ExtensionError(ExtensionError::JAVASCRIPT_RUNTIME_ERROR,
103 std::string(), // We don't know the id yet. 160 std::string(), // We don't know the id yet.
104 from_incognito, 161 from_incognito,
105 source, 162 source,
106 message), 163 message),
107 level_(level) { 164 level_(level) {
108 ParseDetails(details); 165 ParseDetails(details);
109 DetermineExtensionID(); 166 DetermineExtensionId();
110 } 167 }
111 168
112 JavascriptRuntimeError::~JavascriptRuntimeError() { 169 JavascriptRuntimeError::~JavascriptRuntimeError() {
113 } 170 }
114 171
115 std::string JavascriptRuntimeError::PrintForTest() const { 172 std::string JavascriptRuntimeError::PrintForTest() const {
116 std::string result = ExtensionError::PrintForTest() + 173 std::string result = ExtensionError::PrintForTest() +
117 "\n Type: JavascriptRuntimeError" 174 "\n Type: JavascriptRuntimeError"
118 "\n Context: " + base::UTF16ToUTF8(execution_context_url_) + 175 "\n Context: " + base::UTF16ToUTF8(execution_context_url_) +
119 "\n Stack Trace: "; 176 "\n Stack Trace: ";
120 for (StackTrace::const_iterator iter = stack_trace_.begin(); 177 for (StackTrace::const_iterator iter = stack_trace_.begin();
121 iter != stack_trace_.end(); ++iter) { 178 iter != stack_trace_.end(); ++iter) {
122 result += "\n {" 179 result += "\n {"
123 "\n Line: " + base::IntToString(iter->line_number) + 180 "\n Line: " + base::IntToString(iter->line_number) +
124 "\n Column: " + base::IntToString(iter->column_number) + 181 "\n Column: " + base::IntToString(iter->column_number) +
125 "\n URL: " + base::UTF16ToUTF8(iter->url) + 182 "\n URL: " + base::UTF16ToUTF8(iter->url) +
126 "\n Function: " + base::UTF16ToUTF8(iter->function) + 183 "\n Function: " + base::UTF16ToUTF8(iter->function) +
127 "\n }"; 184 "\n }";
128 } 185 }
129 return result; 186 return result;
130 } 187 }
131 188
189 bool JavascriptRuntimeError::IsEqualImpl(const ExtensionError* rhs) const {
190 const JavascriptRuntimeError* error =
191 static_cast<const JavascriptRuntimeError*>(rhs);
192
193 // We don't look at the full stack trace, because if the first frame is
194 // the same, it's close enough to heuristically count as a duplicate (after
195 // all, the same line caused the error).
196 // If the stack trace is empty, just compare the context.
197 return execution_context_url_ == error->execution_context_url_ &&
198 stack_trace_.size() == error->stack_trace_.size() &&
199 (stack_trace_.empty() || stack_trace_[0] == error->stack_trace_[0]);
200 }
201
132 void JavascriptRuntimeError::ParseDetails(const string16& details) { 202 void JavascriptRuntimeError::ParseDetails(const string16& details) {
133 scoped_ptr<base::Value> value( 203 scoped_ptr<base::Value> value(
134 base::JSONReader::Read(base::UTF16ToUTF8(details))); 204 base::JSONReader::Read(base::UTF16ToUTF8(details)));
135 const base::DictionaryValue* details_value; 205 const DictionaryValue* details_value;
136 const base::ListValue* trace_value = NULL; 206 const base::ListValue* trace_value = NULL;
137 207
138 // The |details| value should contain an execution context url and a stack 208 // The |details| value should contain an execution context url and a stack
139 // trace. 209 // trace.
140 if (!value.get() || 210 if (!value.get() ||
141 !value->GetAsDictionary(&details_value) || 211 !value->GetAsDictionary(&details_value) ||
142 !details_value->GetString(kExecutionContextURLKey, 212 !details_value->GetString(kExecutionContextURLKey,
143 &execution_context_url_) || 213 &execution_context_url_) ||
144 !details_value->GetList(kStackTraceKey, &trace_value)) { 214 !details_value->GetList(kStackTraceKey, &trace_value)) {
145 NOTREACHED(); 215 NOTREACHED();
146 return; 216 return;
147 } 217 }
148 218
149 int line = 0; 219 int line = 0;
150 int column = 0; 220 int column = 0;
151 string16 url; 221 string16 url;
152 222
153 for (size_t i = 0; i < trace_value->GetSize(); ++i) { 223 for (size_t i = 0; i < trace_value->GetSize(); ++i) {
154 const base::DictionaryValue* frame_value = NULL; 224 const DictionaryValue* frame_value = NULL;
155 CHECK(trace_value->GetDictionary(i, &frame_value)); 225 CHECK(trace_value->GetDictionary(i, &frame_value));
156 226
157 frame_value->GetInteger(kLineNumberKey, &line); 227 frame_value->GetInteger(kLineNumberKey, &line);
158 frame_value->GetInteger(kColumnNumberKey, &column); 228 frame_value->GetInteger(kColumnNumberKey, &column);
159 frame_value->GetString(kURLKey, &url); 229 frame_value->GetString(kURLKey, &url);
160 230
161 string16 function; 231 string16 function;
162 frame_value->GetString(kFunctionNameKey, &function); // This can be empty. 232 frame_value->GetString(kFunctionNameKey, &function); // This can be empty.
163 stack_trace_.push_back(StackFrame(line, column, url, function)); 233 stack_trace_.push_back(StackFrame(line, column, url, function));
164 } 234 }
165 } 235 }
166 236
167 void JavascriptRuntimeError::DetermineExtensionID() { 237 void JavascriptRuntimeError::DetermineExtensionId() {
168 if (!GetExtensionIDFromGURL(GURL(source_), &extension_id_)) 238 if (!GetExtensionIdFromGURL(GURL(source_), &extension_id_))
169 GetExtensionIDFromGURL(GURL(execution_context_url_), &extension_id_); 239 GetExtensionIdFromGURL(GURL(execution_context_url_), &extension_id_);
170 } 240 }
171 241
172 } // namespace extensions 242 } // namespace extensions
OLDNEW
« extensions/browser/extension_error.h ('K') | « extensions/browser/extension_error.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698