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

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

Issue 23007021: Report Javascript Runtime Errors to the Error Console (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@dc_ec_feldman
Patch Set: Created 7 years, 3 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
« no previous file with comments | « extensions/browser/extension_error.h ('k') | extensions/common/DEPS » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
8 #include "base/strings/string_number_conversions.h" 7 #include "base/strings/string_number_conversions.h"
9 #include "base/strings/utf_string_conversions.h" 8 #include "base/strings/utf_string_conversions.h"
10 #include "base/values.h" 9 #include "base/values.h"
11 #include "extensions/common/constants.h" 10 #include "extensions/common/constants.h"
12 #include "url/gurl.h" 11 #include "url/gurl.h"
13 12
14 using base::string16; 13 using base::string16;
15 14
16 namespace extensions { 15 namespace extensions {
17 16
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 return ExtensionError::PrintForTest() + 89 return ExtensionError::PrintForTest() +
91 "\n Type: ManifestError"; 90 "\n Type: ManifestError";
92 } 91 }
93 92
94 bool ManifestError::IsEqualImpl(const ExtensionError* rhs) const { 93 bool ManifestError::IsEqualImpl(const ExtensionError* rhs) const {
95 // If two manifest errors have the same extension id and message (which are 94 // If two manifest errors have the same extension id and message (which are
96 // both checked in ExtensionError::IsEqual), then they are equal. 95 // both checked in ExtensionError::IsEqual), then they are equal.
97 return true; 96 return true;
98 } 97 }
99 98
100 RuntimeError::StackFrame::StackFrame() : line_number(-1), column_number(-1) {
101 }
102
103 RuntimeError::StackFrame::StackFrame(size_t frame_line,
104 size_t frame_column,
105 const string16& frame_url,
106 const string16& frame_function)
107 : line_number(frame_line),
108 column_number(frame_column),
109 url(frame_url),
110 function(frame_function) {
111 }
112
113 RuntimeError::StackFrame::~StackFrame() {
114 }
115
116 bool RuntimeError::StackFrame::operator==(
117 const RuntimeError::StackFrame& rhs) const {
118 return line_number == rhs.line_number &&
119 column_number == rhs.column_number &&
120 url == rhs.url &&
121 function == rhs.function;
122 }
123 RuntimeError::RuntimeError(bool from_incognito, 99 RuntimeError::RuntimeError(bool from_incognito,
124 const string16& source, 100 const string16& source,
125 const string16& message, 101 const string16& message,
126 logging::LogSeverity level, 102 const StackTrace& stack_trace,
127 const string16& details) 103 const GURL& context_url,
104 logging::LogSeverity level)
128 : ExtensionError(ExtensionError::RUNTIME_ERROR, 105 : ExtensionError(ExtensionError::RUNTIME_ERROR,
129 std::string(), // We don't know the id yet. 106 GURL(source).host(),
130 from_incognito, 107 from_incognito,
131 level, 108 level,
132 source, 109 source,
133 message) { 110 message),
134 ParseDetails(details); 111 context_url_(context_url),
135 DetermineExtensionID(); 112 stack_trace_(stack_trace) {
113 CleanUpInit();
136 } 114 }
137 115
138 RuntimeError::~RuntimeError() { 116 RuntimeError::~RuntimeError() {
139 } 117 }
140 118
141 std::string RuntimeError::PrintForTest() const { 119 std::string RuntimeError::PrintForTest() const {
142 std::string result = ExtensionError::PrintForTest() + 120 std::string result = ExtensionError::PrintForTest() +
143 "\n Type: RuntimeError" 121 "\n Type: RuntimeError"
144 "\n Context: " + base::UTF16ToUTF8(execution_context_url_) + 122 "\n Context: " + context_url_.spec() +
145 "\n Stack Trace: "; 123 "\n Stack Trace: ";
146 for (StackTrace::const_iterator iter = stack_trace_.begin(); 124 for (StackTrace::const_iterator iter = stack_trace_.begin();
147 iter != stack_trace_.end(); ++iter) { 125 iter != stack_trace_.end(); ++iter) {
148 result += "\n {" 126 result += "\n {"
149 "\n Line: " + base::IntToString(iter->line_number) + 127 "\n Line: " + base::IntToString(iter->line_number) +
150 "\n Column: " + base::IntToString(iter->column_number) + 128 "\n Column: " + base::IntToString(iter->column_number) +
151 "\n URL: " + base::UTF16ToUTF8(iter->url) + 129 "\n URL: " + base::UTF16ToUTF8(iter->source) +
152 "\n Function: " + base::UTF16ToUTF8(iter->function) + 130 "\n Function: " + base::UTF16ToUTF8(iter->function) +
153 "\n }"; 131 "\n }";
154 } 132 }
155 return result; 133 return result;
156 } 134 }
157 135
158 bool RuntimeError::IsEqualImpl(const ExtensionError* rhs) const { 136 bool RuntimeError::IsEqualImpl(const ExtensionError* rhs) const {
159 const RuntimeError* error = static_cast<const RuntimeError*>(rhs); 137 const RuntimeError* error = static_cast<const RuntimeError*>(rhs);
160 138
161 // Only look at the first frame of a stack trace to save time and group 139 // Only look at the first frame of a stack trace to save time and group
162 // nearly-identical errors. The most recent error is kept, so there's no risk 140 // nearly-identical errors. The most recent error is kept, so there's no risk
163 // of displaying an old and inaccurate stack trace. 141 // of displaying an old and inaccurate stack trace.
164 return level_ == level_ && 142 return level_ == level_ &&
165 source_ == source_ && 143 source_ == source_ &&
166 execution_context_url_ == error->execution_context_url_ && 144 context_url_ == error->context_url_ &&
167 stack_trace_.size() == error->stack_trace_.size() && 145 stack_trace_.size() == error->stack_trace_.size() &&
168 (stack_trace_.empty() || stack_trace_[0] == error->stack_trace_[0]); 146 (stack_trace_.empty() || stack_trace_[0] == error->stack_trace_[0]);
169 } 147 }
170 148
171 void RuntimeError::ParseDetails(const string16& details) { 149 void RuntimeError::CleanUpInit() {
172 scoped_ptr<base::Value> value( 150 // If the error came from a generated background page, the "context" is empty
173 base::JSONReader::Read(base::UTF16ToUTF8(details))); 151 // because there's no visible URL. We should set context to be the generated
174 const base::DictionaryValue* details_value; 152 // background page in this case.
175 const base::ListValue* trace_value = NULL; 153 GURL source_url = GURL(source_);
176 154 if (context_url_.is_empty() &&
177 // The |details| value should contain an execution context url and a stack 155 source_url.path() ==
178 // trace. 156 std::string("/") + kGeneratedBackgroundPageFilename) {
179 if (!value.get() || 157 context_url_ = source_url;
180 !value->GetAsDictionary(&details_value) ||
181 !details_value->GetString(kExecutionContextURLKey,
182 &execution_context_url_) ||
183 !details_value->GetList(kStackTraceKey, &trace_value)) {
184 NOTREACHED();
185 return;
186 } 158 }
187 159
188 int line = 0; 160 // In some instances (due to the fact that we're reusing error reporting from
189 int column = 0; 161 // other systems), the source won't match up with the final entry in the stack
190 string16 url; 162 // trace. (For instance, in a browser action error, the source is the page -
191 163 // sometimes the background page - but the error is thrown from the script.)
192 for (size_t i = 0; i < trace_value->GetSize(); ++i) { 164 // Make the source match the stack trace, since that is more likely the cause
193 const base::DictionaryValue* frame_value = NULL; 165 // of the error.
194 CHECK(trace_value->GetDictionary(i, &frame_value)); 166 if (!stack_trace_.empty() && source_ != stack_trace_[0].source)
195 167 source_ = stack_trace_[0].source;
196 frame_value->GetInteger(kLineNumberKey, &line);
197 frame_value->GetInteger(kColumnNumberKey, &column);
198 frame_value->GetString(kURLKey, &url);
199
200 string16 function;
201 frame_value->GetString(kFunctionNameKey, &function); // This can be empty.
202 stack_trace_.push_back(StackFrame(line, column, url, function));
203 }
204 }
205
206 void RuntimeError::DetermineExtensionID() {
207 if (!GetExtensionIDFromGURL(GURL(source_), &extension_id_))
208 GetExtensionIDFromGURL(GURL(execution_context_url_), &extension_id_);
209 } 168 }
210 169
211 } // namespace extensions 170 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/browser/extension_error.h ('k') | extensions/common/DEPS » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698