blob: 15559e0eca11c8b823b4800cb67866163984318e [file] [log] [blame]
[email protected]1b66fdb2013-07-26 09:57:281// Copyright 2013 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
[email protected]921237d062013-08-10 15:30:495#include "extensions/browser/extension_error.h"
[email protected]1b66fdb2013-07-26 09:57:286
[email protected]1b66fdb2013-07-26 09:57:287#include "base/strings/string_number_conversions.h"
8#include "base/strings/utf_string_conversions.h"
[email protected]1b66fdb2013-07-26 09:57:289#include "extensions/common/constants.h"
[email protected]921237d062013-08-10 15:30:4910#include "url/gurl.h"
[email protected]1b66fdb2013-07-26 09:57:2811
[email protected]1b66fdb2013-07-26 09:57:2812namespace extensions {
13
[email protected]fa5fed32013-09-05 21:56:2214////////////////////////////////////////////////////////////////////////////////
15// ExtensionError
[email protected]1b66fdb2013-07-26 09:57:2816
[email protected]1b66fdb2013-07-26 09:57:2817ExtensionError::ExtensionError(Type type,
[email protected]921237d062013-08-10 15:30:4918 const std::string& extension_id,
[email protected]1b66fdb2013-07-26 09:57:2819 bool from_incognito,
[email protected]d466f782013-08-28 21:59:2320 logging::LogSeverity level,
[email protected]0d163dc2013-12-20 23:48:3621 const base::string16& source,
22 const base::string16& message)
[email protected]1b66fdb2013-07-26 09:57:2823 : type_(type),
[email protected]921237d062013-08-10 15:30:4924 extension_id_(extension_id),
rdevlin.croninc799f9f2015-03-21 00:56:3025 id_(0),
[email protected]1b66fdb2013-07-26 09:57:2826 from_incognito_(from_incognito),
[email protected]d466f782013-08-28 21:59:2327 level_(level),
[email protected]1b66fdb2013-07-26 09:57:2828 source_(source),
[email protected]d466f782013-08-28 21:59:2329 message_(message),
30 occurrences_(1u) {
[email protected]1b66fdb2013-07-26 09:57:2831}
32
33ExtensionError::~ExtensionError() {
34}
35
wittmanb3ee0482015-06-24 17:47:4036std::string ExtensionError::GetDebugString() const {
[email protected]1b66fdb2013-07-26 09:57:2837 return std::string("Extension Error:") +
38 "\n OTR: " + std::string(from_incognito_ ? "true" : "false") +
[email protected]50af6082013-09-10 02:05:1939 "\n Level: " + base::IntToString(static_cast<int>(level_)) +
[email protected]1b66fdb2013-07-26 09:57:2840 "\n Source: " + base::UTF16ToUTF8(source_) +
41 "\n Message: " + base::UTF16ToUTF8(message_) +
42 "\n ID: " + extension_id_;
43}
44
[email protected]d466f782013-08-28 21:59:2345bool ExtensionError::IsEqual(const ExtensionError* rhs) const {
46 // We don't check |source_| or |level_| here, since they are constant for
47 // manifest errors. Check them in RuntimeError::IsEqualImpl() instead.
48 return type_ == rhs->type_ &&
49 extension_id_ == rhs->extension_id_ &&
50 message_ == rhs->message_ &&
51 IsEqualImpl(rhs);
52}
53
[email protected]fa5fed32013-09-05 21:56:2254////////////////////////////////////////////////////////////////////////////////
55// ManifestError
56
[email protected]d466f782013-08-28 21:59:2357ManifestError::ManifestError(const std::string& extension_id,
[email protected]0d163dc2013-12-20 23:48:3658 const base::string16& message,
59 const base::string16& manifest_key,
60 const base::string16& manifest_specific)
[email protected]d466f782013-08-28 21:59:2361 : ExtensionError(ExtensionError::MANIFEST_ERROR,
[email protected]921237d062013-08-10 15:30:4962 extension_id,
63 false, // extensions can't be installed while incognito.
[email protected]d466f782013-08-28 21:59:2364 logging::LOG_WARNING, // All manifest errors are warnings.
[email protected]921237d062013-08-10 15:30:4965 base::FilePath(kManifestFilename).AsUTF16Unsafe(),
[email protected]b191e2d32013-09-03 21:08:3066 message),
67 manifest_key_(manifest_key),
68 manifest_specific_(manifest_specific) {
[email protected]1b66fdb2013-07-26 09:57:2869}
70
[email protected]d466f782013-08-28 21:59:2371ManifestError::~ManifestError() {
[email protected]1b66fdb2013-07-26 09:57:2872}
73
wittmanb3ee0482015-06-24 17:47:4074std::string ManifestError::GetDebugString() const {
75 return ExtensionError::GetDebugString() +
[email protected]d466f782013-08-28 21:59:2376 "\n Type: ManifestError";
[email protected]1b66fdb2013-07-26 09:57:2877}
78
[email protected]d466f782013-08-28 21:59:2379bool ManifestError::IsEqualImpl(const ExtensionError* rhs) const {
80 // If two manifest errors have the same extension id and message (which are
81 // both checked in ExtensionError::IsEqual), then they are equal.
82 return true;
[email protected]1b66fdb2013-07-26 09:57:2883}
84
[email protected]2fb9bd22013-09-07 00:08:0885////////////////////////////////////////////////////////////////////////////////
86// RuntimeError
87
[email protected]a0ed2682013-09-06 08:41:0788RuntimeError::RuntimeError(const std::string& extension_id,
89 bool from_incognito,
[email protected]0d163dc2013-12-20 23:48:3690 const base::string16& source,
91 const base::string16& message,
[email protected]88b50b62013-09-01 23:05:0692 const StackTrace& stack_trace,
93 const GURL& context_url,
[email protected]c934c382013-11-01 00:36:0194 logging::LogSeverity level,
rdevlin.cronin86f5b702015-06-24 18:49:1795 int render_frame_id,
[email protected]c934c382013-11-01 00:36:0196 int render_process_id)
[email protected]d466f782013-08-28 21:59:2397 : ExtensionError(ExtensionError::RUNTIME_ERROR,
[email protected]a0ed2682013-09-06 08:41:0798 !extension_id.empty() ? extension_id : GURL(source).host(),
[email protected]1b66fdb2013-07-26 09:57:2899 from_incognito,
[email protected]d466f782013-08-28 21:59:23100 level,
[email protected]1b66fdb2013-07-26 09:57:28101 source,
[email protected]88b50b62013-09-01 23:05:06102 message),
103 context_url_(context_url),
[email protected]c934c382013-11-01 00:36:01104 stack_trace_(stack_trace),
rdevlin.cronin86f5b702015-06-24 18:49:17105 render_frame_id_(render_frame_id),
[email protected]c934c382013-11-01 00:36:01106 render_process_id_(render_process_id) {
[email protected]88b50b62013-09-01 23:05:06107 CleanUpInit();
[email protected]1b66fdb2013-07-26 09:57:28108}
109
[email protected]d466f782013-08-28 21:59:23110RuntimeError::~RuntimeError() {
[email protected]1b66fdb2013-07-26 09:57:28111}
112
wittmanb3ee0482015-06-24 17:47:40113std::string RuntimeError::GetDebugString() const {
114 std::string result = ExtensionError::GetDebugString() +
[email protected]d466f782013-08-28 21:59:23115 "\n Type: RuntimeError"
[email protected]88b50b62013-09-01 23:05:06116 "\n Context: " + context_url_.spec() +
[email protected]1b66fdb2013-07-26 09:57:28117 "\n Stack Trace: ";
118 for (StackTrace::const_iterator iter = stack_trace_.begin();
119 iter != stack_trace_.end(); ++iter) {
riceac7009272015-09-25 18:45:13120 // The "NL" comments are to force clang-format to choose the right layout.
121 result += "\n {";
122 result +=
123 "\n Line: " + base::SizeTToString(iter->line_number) + // NL
124 "\n Column: " + base::SizeTToString(iter->column_number) + // NL
125 "\n URL: " + base::UTF16ToUTF8(iter->source) + // NL
126 "\n Function: " + base::UTF16ToUTF8(iter->function) + // NL
127 "\n }"; // NL
[email protected]1b66fdb2013-07-26 09:57:28128 }
129 return result;
130}
131
[email protected]d466f782013-08-28 21:59:23132bool RuntimeError::IsEqualImpl(const ExtensionError* rhs) const {
133 const RuntimeError* error = static_cast<const RuntimeError*>(rhs);
134
135 // Only look at the first frame of a stack trace to save time and group
136 // nearly-identical errors. The most recent error is kept, so there's no risk
137 // of displaying an old and inaccurate stack trace.
[email protected]010ff5072013-09-10 08:36:50138 return level_ == error->level_ &&
139 source_ == error->source_ &&
[email protected]88b50b62013-09-01 23:05:06140 context_url_ == error->context_url_ &&
[email protected]d466f782013-08-28 21:59:23141 stack_trace_.size() == error->stack_trace_.size() &&
142 (stack_trace_.empty() || stack_trace_[0] == error->stack_trace_[0]);
143}
144
[email protected]88b50b62013-09-01 23:05:06145void RuntimeError::CleanUpInit() {
146 // If the error came from a generated background page, the "context" is empty
147 // because there's no visible URL. We should set context to be the generated
148 // background page in this case.
149 GURL source_url = GURL(source_);
150 if (context_url_.is_empty() &&
csharrison88b3b712016-11-14 23:12:35151 source_url.path_piece() ==
[email protected]88b50b62013-09-01 23:05:06152 std::string("/") + kGeneratedBackgroundPageFilename) {
153 context_url_ = source_url;
[email protected]1b66fdb2013-07-26 09:57:28154 }
155
[email protected]88b50b62013-09-01 23:05:06156 // In some instances (due to the fact that we're reusing error reporting from
157 // other systems), the source won't match up with the final entry in the stack
158 // trace. (For instance, in a browser action error, the source is the page -
159 // sometimes the background page - but the error is thrown from the script.)
160 // Make the source match the stack trace, since that is more likely the cause
161 // of the error.
162 if (!stack_trace_.empty() && source_ != stack_trace_[0].source)
163 source_ = stack_trace_[0].source;
[email protected]1b66fdb2013-07-26 09:57:28164}
165
wittmanb3ee0482015-06-24 17:47:40166////////////////////////////////////////////////////////////////////////////////
167// InternalError
168
169InternalError::InternalError(const std::string& extension_id,
170 const base::string16& message,
171 logging::LogSeverity level)
172 : ExtensionError(ExtensionError::INTERNAL_ERROR,
173 extension_id,
174 false, // not incognito.
175 level,
176 base::string16(),
177 message) {
178}
179
180InternalError::~InternalError() {
181}
182
183std::string InternalError::GetDebugString() const {
184 return ExtensionError::GetDebugString() +
185 "\n Type: InternalError";
186}
187
188bool InternalError::IsEqualImpl(const ExtensionError* rhs) const {
189 // ExtensionError logic is sufficient for comparison.
190 return true;
191}
192
[email protected]1b66fdb2013-07-26 09:57:28193} // namespace extensions