Add ICU message format support
[chromium-blink-merge.git] / extensions / browser / extension_error.cc
blobe3e8b9ce4e378d79b00c3c90b9395e36a5297b0a
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
3 // found in the LICENSE file.
5 #include "extensions/browser/extension_error.h"
7 #include "base/strings/string_number_conversions.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "extensions/common/constants.h"
10 #include "url/gurl.h"
12 namespace extensions {
14 ////////////////////////////////////////////////////////////////////////////////
15 // ExtensionError
17 ExtensionError::ExtensionError(Type type,
18 const std::string& extension_id,
19 bool from_incognito,
20 logging::LogSeverity level,
21 const base::string16& source,
22 const base::string16& message)
23 : type_(type),
24 extension_id_(extension_id),
25 id_(0),
26 from_incognito_(from_incognito),
27 level_(level),
28 source_(source),
29 message_(message),
30 occurrences_(1u) {
33 ExtensionError::~ExtensionError() {
36 std::string ExtensionError::GetDebugString() const {
37 return std::string("Extension Error:") +
38 "\n OTR: " + std::string(from_incognito_ ? "true" : "false") +
39 "\n Level: " + base::IntToString(static_cast<int>(level_)) +
40 "\n Source: " + base::UTF16ToUTF8(source_) +
41 "\n Message: " + base::UTF16ToUTF8(message_) +
42 "\n ID: " + extension_id_;
45 bool 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);
54 ////////////////////////////////////////////////////////////////////////////////
55 // ManifestError
57 ManifestError::ManifestError(const std::string& extension_id,
58 const base::string16& message,
59 const base::string16& manifest_key,
60 const base::string16& manifest_specific)
61 : ExtensionError(ExtensionError::MANIFEST_ERROR,
62 extension_id,
63 false, // extensions can't be installed while incognito.
64 logging::LOG_WARNING, // All manifest errors are warnings.
65 base::FilePath(kManifestFilename).AsUTF16Unsafe(),
66 message),
67 manifest_key_(manifest_key),
68 manifest_specific_(manifest_specific) {
71 ManifestError::~ManifestError() {
74 std::string ManifestError::GetDebugString() const {
75 return ExtensionError::GetDebugString() +
76 "\n Type: ManifestError";
79 bool 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;
85 ////////////////////////////////////////////////////////////////////////////////
86 // RuntimeError
88 RuntimeError::RuntimeError(const std::string& extension_id,
89 bool from_incognito,
90 const base::string16& source,
91 const base::string16& message,
92 const StackTrace& stack_trace,
93 const GURL& context_url,
94 logging::LogSeverity level,
95 int render_frame_id,
96 int render_process_id)
97 : ExtensionError(ExtensionError::RUNTIME_ERROR,
98 !extension_id.empty() ? extension_id : GURL(source).host(),
99 from_incognito,
100 level,
101 source,
102 message),
103 context_url_(context_url),
104 stack_trace_(stack_trace),
105 render_frame_id_(render_frame_id),
106 render_process_id_(render_process_id) {
107 CleanUpInit();
110 RuntimeError::~RuntimeError() {
113 std::string RuntimeError::GetDebugString() const {
114 std::string result = ExtensionError::GetDebugString() +
115 "\n Type: RuntimeError"
116 "\n Context: " + context_url_.spec() +
117 "\n Stack Trace: ";
118 for (StackTrace::const_iterator iter = stack_trace_.begin();
119 iter != stack_trace_.end(); ++iter) {
120 result += "\n {"
121 "\n Line: " + base::IntToString(iter->line_number) +
122 "\n Column: " + base::IntToString(iter->column_number) +
123 "\n URL: " + base::UTF16ToUTF8(iter->source) +
124 "\n Function: " + base::UTF16ToUTF8(iter->function) +
125 "\n }";
127 return result;
130 bool RuntimeError::IsEqualImpl(const ExtensionError* rhs) const {
131 const RuntimeError* error = static_cast<const RuntimeError*>(rhs);
133 // Only look at the first frame of a stack trace to save time and group
134 // nearly-identical errors. The most recent error is kept, so there's no risk
135 // of displaying an old and inaccurate stack trace.
136 return level_ == error->level_ &&
137 source_ == error->source_ &&
138 context_url_ == error->context_url_ &&
139 stack_trace_.size() == error->stack_trace_.size() &&
140 (stack_trace_.empty() || stack_trace_[0] == error->stack_trace_[0]);
143 void RuntimeError::CleanUpInit() {
144 // If the error came from a generated background page, the "context" is empty
145 // because there's no visible URL. We should set context to be the generated
146 // background page in this case.
147 GURL source_url = GURL(source_);
148 if (context_url_.is_empty() &&
149 source_url.path() ==
150 std::string("/") + kGeneratedBackgroundPageFilename) {
151 context_url_ = source_url;
154 // In some instances (due to the fact that we're reusing error reporting from
155 // other systems), the source won't match up with the final entry in the stack
156 // trace. (For instance, in a browser action error, the source is the page -
157 // sometimes the background page - but the error is thrown from the script.)
158 // Make the source match the stack trace, since that is more likely the cause
159 // of the error.
160 if (!stack_trace_.empty() && source_ != stack_trace_[0].source)
161 source_ = stack_trace_[0].source;
164 ////////////////////////////////////////////////////////////////////////////////
165 // InternalError
167 InternalError::InternalError(const std::string& extension_id,
168 const base::string16& message,
169 logging::LogSeverity level)
170 : ExtensionError(ExtensionError::INTERNAL_ERROR,
171 extension_id,
172 false, // not incognito.
173 level,
174 base::string16(),
175 message) {
178 InternalError::~InternalError() {
181 std::string InternalError::GetDebugString() const {
182 return ExtensionError::GetDebugString() +
183 "\n Type: InternalError";
186 bool InternalError::IsEqualImpl(const ExtensionError* rhs) const {
187 // ExtensionError logic is sufficient for comparison.
188 return true;
191 } // namespace extensions