Avi Drissman | 60039d4 | 2022-09-13 21:49:05 | [diff] [blame] | 1 | // Copyright 2013 The Chromium Authors |
[email protected] | 1b66fdb | 2013-07-26 09:57:28 | [diff] [blame] | 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] | 921237d06 | 2013-08-10 15:30:49 | [diff] [blame] | 5 | #include "extensions/browser/extension_error.h" |
[email protected] | 1b66fdb | 2013-07-26 09:57:28 | [diff] [blame] | 6 | |
[email protected] | 1b66fdb | 2013-07-26 09:57:28 | [diff] [blame] | 7 | #include "base/strings/string_number_conversions.h" |
| 8 | #include "base/strings/utf_string_conversions.h" |
[email protected] | 1b66fdb | 2013-07-26 09:57:28 | [diff] [blame] | 9 | #include "extensions/common/constants.h" |
[email protected] | 921237d06 | 2013-08-10 15:30:49 | [diff] [blame] | 10 | #include "url/gurl.h" |
[email protected] | 1b66fdb | 2013-07-26 09:57:28 | [diff] [blame] | 11 | |
[email protected] | 1b66fdb | 2013-07-26 09:57:28 | [diff] [blame] | 12 | namespace extensions { |
| 13 | |
[email protected] | fa5fed3 | 2013-09-05 21:56:22 | [diff] [blame] | 14 | //////////////////////////////////////////////////////////////////////////////// |
| 15 | // ExtensionError |
[email protected] | 1b66fdb | 2013-07-26 09:57:28 | [diff] [blame] | 16 | |
[email protected] | 1b66fdb | 2013-07-26 09:57:28 | [diff] [blame] | 17 | ExtensionError::ExtensionError(Type type, |
[email protected] | 921237d06 | 2013-08-10 15:30:49 | [diff] [blame] | 18 | const std::string& extension_id, |
[email protected] | 1b66fdb | 2013-07-26 09:57:28 | [diff] [blame] | 19 | bool from_incognito, |
[email protected] | d466f78 | 2013-08-28 21:59:23 | [diff] [blame] | 20 | logging::LogSeverity level, |
Jan Wilken Dörrie | 85285b0 | 2021-03-11 23:38:47 | [diff] [blame] | 21 | const std::u16string& source, |
| 22 | const std::u16string& message) |
[email protected] | 1b66fdb | 2013-07-26 09:57:28 | [diff] [blame] | 23 | : type_(type), |
[email protected] | 921237d06 | 2013-08-10 15:30:49 | [diff] [blame] | 24 | extension_id_(extension_id), |
rdevlin.cronin | c799f9f | 2015-03-21 00:56:30 | [diff] [blame] | 25 | id_(0), |
[email protected] | 1b66fdb | 2013-07-26 09:57:28 | [diff] [blame] | 26 | from_incognito_(from_incognito), |
[email protected] | d466f78 | 2013-08-28 21:59:23 | [diff] [blame] | 27 | level_(level), |
[email protected] | 1b66fdb | 2013-07-26 09:57:28 | [diff] [blame] | 28 | source_(source), |
[email protected] | d466f78 | 2013-08-28 21:59:23 | [diff] [blame] | 29 | message_(message), |
Jan Wilken Dörrie | 85285b0 | 2021-03-11 23:38:47 | [diff] [blame] | 30 | occurrences_(1u) {} |
[email protected] | 1b66fdb | 2013-07-26 09:57:28 | [diff] [blame] | 31 | |
| 32 | ExtensionError::~ExtensionError() { |
| 33 | } |
| 34 | |
wittman | b3ee048 | 2015-06-24 17:47:40 | [diff] [blame] | 35 | std::string ExtensionError::GetDebugString() const { |
[email protected] | 1b66fdb | 2013-07-26 09:57:28 | [diff] [blame] | 36 | return std::string("Extension Error:") + |
| 37 | "\n OTR: " + std::string(from_incognito_ ? "true" : "false") + |
Raul Tambre | 8d92258 | 2019-02-05 20:58:55 | [diff] [blame] | 38 | "\n Level: " + base::NumberToString(level_) + |
[email protected] | 1b66fdb | 2013-07-26 09:57:28 | [diff] [blame] | 39 | "\n Source: " + base::UTF16ToUTF8(source_) + |
| 40 | "\n Message: " + base::UTF16ToUTF8(message_) + |
| 41 | "\n ID: " + extension_id_; |
| 42 | } |
| 43 | |
[email protected] | d466f78 | 2013-08-28 21:59:23 | [diff] [blame] | 44 | bool ExtensionError::IsEqual(const ExtensionError* rhs) const { |
| 45 | // We don't check |source_| or |level_| here, since they are constant for |
| 46 | // manifest errors. Check them in RuntimeError::IsEqualImpl() instead. |
| 47 | return type_ == rhs->type_ && |
| 48 | extension_id_ == rhs->extension_id_ && |
| 49 | message_ == rhs->message_ && |
| 50 | IsEqualImpl(rhs); |
| 51 | } |
| 52 | |
[email protected] | fa5fed3 | 2013-09-05 21:56:22 | [diff] [blame] | 53 | //////////////////////////////////////////////////////////////////////////////// |
| 54 | // ManifestError |
| 55 | |
[email protected] | d466f78 | 2013-08-28 21:59:23 | [diff] [blame] | 56 | ManifestError::ManifestError(const std::string& extension_id, |
Jan Wilken Dörrie | 85285b0 | 2021-03-11 23:38:47 | [diff] [blame] | 57 | const std::u16string& message, |
| 58 | const std::u16string& manifest_key, |
| 59 | const std::u16string& manifest_specific) |
[email protected] | d466f78 | 2013-08-28 21:59:23 | [diff] [blame] | 60 | : ExtensionError(ExtensionError::MANIFEST_ERROR, |
[email protected] | 921237d06 | 2013-08-10 15:30:49 | [diff] [blame] | 61 | extension_id, |
| 62 | false, // extensions can't be installed while incognito. |
[email protected] | d466f78 | 2013-08-28 21:59:23 | [diff] [blame] | 63 | logging::LOG_WARNING, // All manifest errors are warnings. |
[email protected] | 921237d06 | 2013-08-10 15:30:49 | [diff] [blame] | 64 | base::FilePath(kManifestFilename).AsUTF16Unsafe(), |
[email protected] | b191e2d3 | 2013-09-03 21:08:30 | [diff] [blame] | 65 | message), |
| 66 | manifest_key_(manifest_key), |
Jan Wilken Dörrie | 85285b0 | 2021-03-11 23:38:47 | [diff] [blame] | 67 | manifest_specific_(manifest_specific) {} |
[email protected] | 1b66fdb | 2013-07-26 09:57:28 | [diff] [blame] | 68 | |
[email protected] | d466f78 | 2013-08-28 21:59:23 | [diff] [blame] | 69 | ManifestError::~ManifestError() { |
[email protected] | 1b66fdb | 2013-07-26 09:57:28 | [diff] [blame] | 70 | } |
| 71 | |
wittman | b3ee048 | 2015-06-24 17:47:40 | [diff] [blame] | 72 | std::string ManifestError::GetDebugString() const { |
| 73 | return ExtensionError::GetDebugString() + |
[email protected] | d466f78 | 2013-08-28 21:59:23 | [diff] [blame] | 74 | "\n Type: ManifestError"; |
[email protected] | 1b66fdb | 2013-07-26 09:57:28 | [diff] [blame] | 75 | } |
| 76 | |
[email protected] | d466f78 | 2013-08-28 21:59:23 | [diff] [blame] | 77 | bool ManifestError::IsEqualImpl(const ExtensionError* rhs) const { |
| 78 | // If two manifest errors have the same extension id and message (which are |
| 79 | // both checked in ExtensionError::IsEqual), then they are equal. |
| 80 | return true; |
[email protected] | 1b66fdb | 2013-07-26 09:57:28 | [diff] [blame] | 81 | } |
| 82 | |
[email protected] | 2fb9bd2 | 2013-09-07 00:08:08 | [diff] [blame] | 83 | //////////////////////////////////////////////////////////////////////////////// |
| 84 | // RuntimeError |
| 85 | |
[email protected] | a0ed268 | 2013-09-06 08:41:07 | [diff] [blame] | 86 | RuntimeError::RuntimeError(const std::string& extension_id, |
| 87 | bool from_incognito, |
Jan Wilken Dörrie | 85285b0 | 2021-03-11 23:38:47 | [diff] [blame] | 88 | const std::u16string& source, |
| 89 | const std::u16string& message, |
[email protected] | 88b50b6 | 2013-09-01 23:05:06 | [diff] [blame] | 90 | const StackTrace& stack_trace, |
| 91 | const GURL& context_url, |
[email protected] | c934c38 | 2013-11-01 00:36:01 | [diff] [blame] | 92 | logging::LogSeverity level, |
rdevlin.cronin | 86f5b70 | 2015-06-24 18:49:17 | [diff] [blame] | 93 | int render_frame_id, |
[email protected] | c934c38 | 2013-11-01 00:36:01 | [diff] [blame] | 94 | int render_process_id) |
[email protected] | d466f78 | 2013-08-28 21:59:23 | [diff] [blame] | 95 | : ExtensionError(ExtensionError::RUNTIME_ERROR, |
[email protected] | a0ed268 | 2013-09-06 08:41:07 | [diff] [blame] | 96 | !extension_id.empty() ? extension_id : GURL(source).host(), |
[email protected] | 1b66fdb | 2013-07-26 09:57:28 | [diff] [blame] | 97 | from_incognito, |
[email protected] | d466f78 | 2013-08-28 21:59:23 | [diff] [blame] | 98 | level, |
[email protected] | 1b66fdb | 2013-07-26 09:57:28 | [diff] [blame] | 99 | source, |
[email protected] | 88b50b6 | 2013-09-01 23:05:06 | [diff] [blame] | 100 | message), |
| 101 | context_url_(context_url), |
[email protected] | c934c38 | 2013-11-01 00:36:01 | [diff] [blame] | 102 | stack_trace_(stack_trace), |
rdevlin.cronin | 86f5b70 | 2015-06-24 18:49:17 | [diff] [blame] | 103 | render_frame_id_(render_frame_id), |
[email protected] | c934c38 | 2013-11-01 00:36:01 | [diff] [blame] | 104 | render_process_id_(render_process_id) { |
[email protected] | 88b50b6 | 2013-09-01 23:05:06 | [diff] [blame] | 105 | CleanUpInit(); |
[email protected] | 1b66fdb | 2013-07-26 09:57:28 | [diff] [blame] | 106 | } |
| 107 | |
[email protected] | d466f78 | 2013-08-28 21:59:23 | [diff] [blame] | 108 | RuntimeError::~RuntimeError() { |
[email protected] | 1b66fdb | 2013-07-26 09:57:28 | [diff] [blame] | 109 | } |
| 110 | |
wittman | b3ee048 | 2015-06-24 17:47:40 | [diff] [blame] | 111 | std::string RuntimeError::GetDebugString() const { |
| 112 | std::string result = ExtensionError::GetDebugString() + |
[email protected] | d466f78 | 2013-08-28 21:59:23 | [diff] [blame] | 113 | "\n Type: RuntimeError" |
[email protected] | 88b50b6 | 2013-09-01 23:05:06 | [diff] [blame] | 114 | "\n Context: " + context_url_.spec() + |
[email protected] | 1b66fdb | 2013-07-26 09:57:28 | [diff] [blame] | 115 | "\n Stack Trace: "; |
jdoerrie | a1e1598b | 2018-10-10 09:10:37 | [diff] [blame] | 116 | for (auto iter = stack_trace_.cbegin(); iter != stack_trace_.cend(); ++iter) { |
ricea | c700927 | 2015-09-25 18:45:13 | [diff] [blame] | 117 | result += "\n {"; |
Brett Wilson | 5accd24 | 2017-11-30 22:07:32 | [diff] [blame] | 118 | result += "\n Line: " + base::NumberToString(iter->line_number) + |
| 119 | "\n Column: " + base::NumberToString(iter->column_number) + |
| 120 | "\n URL: " + base::UTF16ToUTF8(iter->source) + |
| 121 | "\n Function: " + base::UTF16ToUTF8(iter->function) + |
| 122 | "\n }"; |
[email protected] | 1b66fdb | 2013-07-26 09:57:28 | [diff] [blame] | 123 | } |
| 124 | return result; |
| 125 | } |
| 126 | |
[email protected] | d466f78 | 2013-08-28 21:59:23 | [diff] [blame] | 127 | bool RuntimeError::IsEqualImpl(const ExtensionError* rhs) const { |
| 128 | const RuntimeError* error = static_cast<const RuntimeError*>(rhs); |
| 129 | |
| 130 | // Only look at the first frame of a stack trace to save time and group |
| 131 | // nearly-identical errors. The most recent error is kept, so there's no risk |
| 132 | // of displaying an old and inaccurate stack trace. |
[email protected] | 010ff507 | 2013-09-10 08:36:50 | [diff] [blame] | 133 | return level_ == error->level_ && |
| 134 | source_ == error->source_ && |
[email protected] | 88b50b6 | 2013-09-01 23:05:06 | [diff] [blame] | 135 | context_url_ == error->context_url_ && |
[email protected] | d466f78 | 2013-08-28 21:59:23 | [diff] [blame] | 136 | stack_trace_.size() == error->stack_trace_.size() && |
| 137 | (stack_trace_.empty() || stack_trace_[0] == error->stack_trace_[0]); |
| 138 | } |
| 139 | |
[email protected] | 88b50b6 | 2013-09-01 23:05:06 | [diff] [blame] | 140 | void RuntimeError::CleanUpInit() { |
| 141 | // If the error came from a generated background page, the "context" is empty |
| 142 | // because there's no visible URL. We should set context to be the generated |
| 143 | // background page in this case. |
| 144 | GURL source_url = GURL(source_); |
| 145 | if (context_url_.is_empty() && |
csharrison | 88b3b71 | 2016-11-14 23:12:35 | [diff] [blame] | 146 | source_url.path_piece() == |
[email protected] | 88b50b6 | 2013-09-01 23:05:06 | [diff] [blame] | 147 | std::string("/") + kGeneratedBackgroundPageFilename) { |
| 148 | context_url_ = source_url; |
[email protected] | 1b66fdb | 2013-07-26 09:57:28 | [diff] [blame] | 149 | } |
| 150 | |
[email protected] | 88b50b6 | 2013-09-01 23:05:06 | [diff] [blame] | 151 | // In some instances (due to the fact that we're reusing error reporting from |
| 152 | // other systems), the source won't match up with the final entry in the stack |
| 153 | // trace. (For instance, in a browser action error, the source is the page - |
| 154 | // sometimes the background page - but the error is thrown from the script.) |
| 155 | // Make the source match the stack trace, since that is more likely the cause |
| 156 | // of the error. |
| 157 | if (!stack_trace_.empty() && source_ != stack_trace_[0].source) |
| 158 | source_ = stack_trace_[0].source; |
[email protected] | 1b66fdb | 2013-07-26 09:57:28 | [diff] [blame] | 159 | } |
| 160 | |
wittman | b3ee048 | 2015-06-24 17:47:40 | [diff] [blame] | 161 | //////////////////////////////////////////////////////////////////////////////// |
| 162 | // InternalError |
| 163 | |
| 164 | InternalError::InternalError(const std::string& extension_id, |
Jan Wilken Dörrie | 85285b0 | 2021-03-11 23:38:47 | [diff] [blame] | 165 | const std::u16string& message, |
wittman | b3ee048 | 2015-06-24 17:47:40 | [diff] [blame] | 166 | logging::LogSeverity level) |
| 167 | : ExtensionError(ExtensionError::INTERNAL_ERROR, |
| 168 | extension_id, |
| 169 | false, // not incognito. |
| 170 | level, |
Jan Wilken Dörrie | 85285b0 | 2021-03-11 23:38:47 | [diff] [blame] | 171 | std::u16string(), |
| 172 | message) {} |
wittman | b3ee048 | 2015-06-24 17:47:40 | [diff] [blame] | 173 | |
| 174 | InternalError::~InternalError() { |
| 175 | } |
| 176 | |
| 177 | std::string InternalError::GetDebugString() const { |
| 178 | return ExtensionError::GetDebugString() + |
| 179 | "\n Type: InternalError"; |
| 180 | } |
| 181 | |
| 182 | bool InternalError::IsEqualImpl(const ExtensionError* rhs) const { |
| 183 | // ExtensionError logic is sufficient for comparison. |
| 184 | return true; |
| 185 | } |
| 186 | |
[email protected] | 1b66fdb | 2013-07-26 09:57:28 | [diff] [blame] | 187 | } // namespace extensions |