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"
12 namespace extensions
{
14 ////////////////////////////////////////////////////////////////////////////////
17 ExtensionError::ExtensionError(Type type
,
18 const std::string
& extension_id
,
20 logging::LogSeverity level
,
21 const base::string16
& source
,
22 const base::string16
& message
)
24 extension_id_(extension_id
),
26 from_incognito_(from_incognito
),
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_
&&
54 ////////////////////////////////////////////////////////////////////////////////
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
,
63 false, // extensions can't be installed while incognito.
64 logging::LOG_WARNING
, // All manifest errors are warnings.
65 base::FilePath(kManifestFilename
).AsUTF16Unsafe(),
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.
85 ////////////////////////////////////////////////////////////////////////////////
88 RuntimeError::RuntimeError(const std::string
& extension_id
,
90 const base::string16
& source
,
91 const base::string16
& message
,
92 const StackTrace
& stack_trace
,
93 const GURL
& context_url
,
94 logging::LogSeverity level
,
96 int render_process_id
)
97 : ExtensionError(ExtensionError::RUNTIME_ERROR
,
98 !extension_id
.empty() ? extension_id
: GURL(source
).host(),
103 context_url_(context_url
),
104 stack_trace_(stack_trace
),
105 render_frame_id_(render_frame_id
),
106 render_process_id_(render_process_id
) {
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() +
118 for (StackTrace::const_iterator iter
= stack_trace_
.begin();
119 iter
!= stack_trace_
.end(); ++iter
) {
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
) +
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() &&
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
160 if (!stack_trace_
.empty() && source_
!= stack_trace_
[0].source
)
161 source_
= stack_trace_
[0].source
;
164 ////////////////////////////////////////////////////////////////////////////////
167 InternalError::InternalError(const std::string
& extension_id
,
168 const base::string16
& message
,
169 logging::LogSeverity level
)
170 : ExtensionError(ExtensionError::INTERNAL_ERROR
,
172 false, // not incognito.
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.
191 } // namespace extensions