summaryrefslogtreecommitdiffstats
path: root/extensions
diff options
context:
space:
mode:
authorrdevlin.cronin@chromium.org <rdevlin.cronin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-28 21:59:23 +0000
committerrdevlin.cronin@chromium.org <rdevlin.cronin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-28 21:59:23 +0000
commitd466f7818d5f44765b6fe153214306e3b6d8be8e (patch)
treeaf1e77ee7b54e7142323bce8f780cf606ebe3aa6 /extensions
parentd9ca99e79006906b12f23b33bbb6341259ae3055 (diff)
downloadchromium_src-d466f7818d5f44765b6fe153214306e3b6d8be8e.zip
chromium_src-d466f7818d5f44765b6fe153214306e3b6d8be8e.tar.gz
chromium_src-d466f7818d5f44765b6fe153214306e3b6d8be8e.tar.bz2
ErrorConsole Switch, Duplicate Error Detection, Dev Mode Check
Add in a command-line switch for ErrorConsole ('enable-error-console'). Add in duplicate-error detection, so that multiple copies of the same error aren't both stored. Add in a check so that the ErrorConsole only stores errors if the user is in Developer Mode. Rename ManifestParsingError to ManifestError, JavascriptRuntimeError to RuntimeError BUG=21734 Review URL: https://chromiumcodereview.appspot.com/23311011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@220108 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'extensions')
-rw-r--r--extensions/browser/extension_error.cc93
-rw-r--r--extensions/browser/extension_error.h56
-rw-r--r--extensions/common/switches.cc4
-rw-r--r--extensions/common/switches.h1
4 files changed, 108 insertions, 46 deletions
diff --git a/extensions/browser/extension_error.cc b/extensions/browser/extension_error.cc
index 8b6196c..eaef221 100644
--- a/extensions/browser/extension_error.cc
+++ b/extensions/browser/extension_error.cc
@@ -40,13 +40,16 @@ bool GetExtensionIDFromGURL(const GURL& url, std::string* extension_id) {
ExtensionError::ExtensionError(Type type,
const std::string& extension_id,
bool from_incognito,
+ logging::LogSeverity level,
const string16& source,
const string16& message)
: type_(type),
extension_id_(extension_id),
from_incognito_(from_incognito),
+ level_(level),
source_(source),
- message_(message) {
+ message_(message),
+ occurrences_(1u) {
}
ExtensionError::~ExtensionError() {
@@ -55,66 +58,89 @@ ExtensionError::~ExtensionError() {
std::string ExtensionError::PrintForTest() const {
return std::string("Extension Error:") +
"\n OTR: " + std::string(from_incognito_ ? "true" : "false") +
+ "\n Level: " + base::IntToString(static_cast<int>(level_));
"\n Source: " + base::UTF16ToUTF8(source_) +
"\n Message: " + base::UTF16ToUTF8(message_) +
"\n ID: " + extension_id_;
}
-ManifestParsingError::ManifestParsingError(const std::string& extension_id,
- const string16& message)
- : ExtensionError(ExtensionError::MANIFEST_PARSING_ERROR,
+bool ExtensionError::IsEqual(const ExtensionError* rhs) const {
+ // We don't check |source_| or |level_| here, since they are constant for
+ // manifest errors. Check them in RuntimeError::IsEqualImpl() instead.
+ return type_ == rhs->type_ &&
+ extension_id_ == rhs->extension_id_ &&
+ message_ == rhs->message_ &&
+ IsEqualImpl(rhs);
+}
+
+ManifestError::ManifestError(const std::string& extension_id,
+ const string16& message)
+ : ExtensionError(ExtensionError::MANIFEST_ERROR,
extension_id,
false, // extensions can't be installed while incognito.
+ logging::LOG_WARNING, // All manifest errors are warnings.
base::FilePath(kManifestFilename).AsUTF16Unsafe(),
message) {
}
-ManifestParsingError::~ManifestParsingError() {
+ManifestError::~ManifestError() {
}
-std::string ManifestParsingError::PrintForTest() const {
+std::string ManifestError::PrintForTest() const {
return ExtensionError::PrintForTest() +
- "\n Type: ManifestParsingError";
+ "\n Type: ManifestError";
+}
+
+bool ManifestError::IsEqualImpl(const ExtensionError* rhs) const {
+ // If two manifest errors have the same extension id and message (which are
+ // both checked in ExtensionError::IsEqual), then they are equal.
+ return true;
}
-JavascriptRuntimeError::StackFrame::StackFrame() : line_number(-1),
- column_number(-1) {
+RuntimeError::StackFrame::StackFrame() : line_number(-1), column_number(-1) {
}
-JavascriptRuntimeError::StackFrame::StackFrame(size_t frame_line,
- size_t frame_column,
- const string16& frame_url,
- const string16& frame_function)
+RuntimeError::StackFrame::StackFrame(size_t frame_line,
+ size_t frame_column,
+ const string16& frame_url,
+ const string16& frame_function)
: line_number(frame_line),
column_number(frame_column),
url(frame_url),
function(frame_function) {
}
-JavascriptRuntimeError::StackFrame::~StackFrame() {
+RuntimeError::StackFrame::~StackFrame() {
}
-JavascriptRuntimeError::JavascriptRuntimeError(bool from_incognito,
- const string16& source,
- const string16& message,
- logging::LogSeverity level,
- const string16& details)
- : ExtensionError(ExtensionError::JAVASCRIPT_RUNTIME_ERROR,
+bool RuntimeError::StackFrame::operator==(
+ const RuntimeError::StackFrame& rhs) const {
+ return line_number == rhs.line_number &&
+ column_number == rhs.column_number &&
+ url == rhs.url &&
+ function == rhs.function;
+}
+RuntimeError::RuntimeError(bool from_incognito,
+ const string16& source,
+ const string16& message,
+ logging::LogSeverity level,
+ const string16& details)
+ : ExtensionError(ExtensionError::RUNTIME_ERROR,
std::string(), // We don't know the id yet.
from_incognito,
+ level,
source,
- message),
- level_(level) {
+ message) {
ParseDetails(details);
DetermineExtensionID();
}
-JavascriptRuntimeError::~JavascriptRuntimeError() {
+RuntimeError::~RuntimeError() {
}
-std::string JavascriptRuntimeError::PrintForTest() const {
+std::string RuntimeError::PrintForTest() const {
std::string result = ExtensionError::PrintForTest() +
- "\n Type: JavascriptRuntimeError"
+ "\n Type: RuntimeError"
"\n Context: " + base::UTF16ToUTF8(execution_context_url_) +
"\n Stack Trace: ";
for (StackTrace::const_iterator iter = stack_trace_.begin();
@@ -129,7 +155,20 @@ std::string JavascriptRuntimeError::PrintForTest() const {
return result;
}
-void JavascriptRuntimeError::ParseDetails(const string16& details) {
+bool RuntimeError::IsEqualImpl(const ExtensionError* rhs) const {
+ const RuntimeError* error = static_cast<const RuntimeError*>(rhs);
+
+ // Only look at the first frame of a stack trace to save time and group
+ // nearly-identical errors. The most recent error is kept, so there's no risk
+ // of displaying an old and inaccurate stack trace.
+ return level_ == level_ &&
+ source_ == source_ &&
+ execution_context_url_ == error->execution_context_url_ &&
+ stack_trace_.size() == error->stack_trace_.size() &&
+ (stack_trace_.empty() || stack_trace_[0] == error->stack_trace_[0]);
+}
+
+void RuntimeError::ParseDetails(const string16& details) {
scoped_ptr<base::Value> value(
base::JSONReader::Read(base::UTF16ToUTF8(details)));
const base::DictionaryValue* details_value;
@@ -164,7 +203,7 @@ void JavascriptRuntimeError::ParseDetails(const string16& details) {
}
}
-void JavascriptRuntimeError::DetermineExtensionID() {
+void RuntimeError::DetermineExtensionID() {
if (!GetExtensionIDFromGURL(GURL(source_), &extension_id_))
GetExtensionIDFromGURL(GURL(execution_context_url_), &extension_id_);
}
diff --git a/extensions/browser/extension_error.h b/extensions/browser/extension_error.h
index 1cd4a7b..c5be169 100644
--- a/extensions/browser/extension_error.h
+++ b/extensions/browser/extension_error.h
@@ -17,55 +17,71 @@ namespace extensions {
class ExtensionError {
public:
enum Type {
- MANIFEST_PARSING_ERROR,
- JAVASCRIPT_RUNTIME_ERROR
+ MANIFEST_ERROR,
+ RUNTIME_ERROR
};
virtual ~ExtensionError();
virtual std::string PrintForTest() const;
+ // Return true if this error and |rhs| are considered equal, and should be
+ // grouped together.
+ bool IsEqual(const ExtensionError* rhs) const;
+
Type type() const { return type_; }
- const base::string16& source() const { return source_; }
- const base::string16& message() const { return message_; }
const std::string& extension_id() const { return extension_id_; }
bool from_incognito() const { return from_incognito_; }
+ logging::LogSeverity level() const { return level_; }
+ const base::string16& source() const { return source_; }
+ const base::string16& message() const { return message_; }
+ size_t occurrences() const { return occurrences_; }
+ void set_occurrences(size_t occurrences) { occurrences_ = occurrences; }
protected:
ExtensionError(Type type,
const std::string& extension_id,
bool from_incognito,
+ logging::LogSeverity level,
const base::string16& source,
const base::string16& message);
+ virtual bool IsEqualImpl(const ExtensionError* rhs) const = 0;
+
// Which type of error this is.
Type type_;
// The ID of the extension which caused the error.
std::string extension_id_;
// Whether or not the error was caused while incognito.
bool from_incognito_;
+ // The severity level of the error.
+ logging::LogSeverity level_;
// The source for the error; this can be a script, web page, or manifest file.
// This is stored as a string (rather than a url) since it can be a Chrome
// script file (e.g., event_bindings.js).
base::string16 source_;
// The error message itself.
base::string16 message_;
+ // The number of times this error has occurred.
+ size_t occurrences_;
DISALLOW_COPY_AND_ASSIGN(ExtensionError);
};
-class ManifestParsingError : public ExtensionError {
+class ManifestError : public ExtensionError {
public:
- ManifestParsingError(const std::string& extension_id,
- const base::string16& message);
- virtual ~ManifestParsingError();
+ ManifestError(const std::string& extension_id,
+ const base::string16& message);
+ virtual ~ManifestError();
virtual std::string PrintForTest() const OVERRIDE;
private:
- DISALLOW_COPY_AND_ASSIGN(ManifestParsingError);
+ virtual bool IsEqualImpl(const ExtensionError* rhs) const OVERRIDE;
+
+ DISALLOW_COPY_AND_ASSIGN(ManifestError);
};
-class JavascriptRuntimeError : public ExtensionError {
+class RuntimeError : public ExtensionError {
public:
struct StackFrame {
size_t line_number;
@@ -84,24 +100,27 @@ class JavascriptRuntimeError : public ExtensionError {
const base::string16& frame_function /* can be empty */);
~StackFrame();
+
+ bool operator==(const StackFrame& rhs) const;
};
typedef std::vector<StackFrame> StackTrace;
- JavascriptRuntimeError(bool from_incognito,
- const base::string16& source,
- const base::string16& message,
- logging::LogSeverity level,
- const base::string16& details);
- virtual ~JavascriptRuntimeError();
+ RuntimeError(bool from_incognito,
+ const base::string16& source,
+ const base::string16& message,
+ logging::LogSeverity level,
+ const base::string16& details);
+ virtual ~RuntimeError();
virtual std::string PrintForTest() const OVERRIDE;
- logging::LogSeverity level() const { return level_; }
const base::string16& execution_context_url() const {
return execution_context_url_;
}
const StackTrace& stack_trace() const { return stack_trace_; }
private:
+ virtual bool IsEqualImpl(const ExtensionError* rhs) const OVERRIDE;
+
// Parse the JSON |details| passed to the error. This includes a stack trace
// and an execution context url.
void ParseDetails(const base::string16& details);
@@ -109,11 +128,10 @@ class JavascriptRuntimeError : public ExtensionError {
// reported source, or through the execution context url.
void DetermineExtensionID();
- logging::LogSeverity level_;
base::string16 execution_context_url_;
StackTrace stack_trace_;
- DISALLOW_COPY_AND_ASSIGN(JavascriptRuntimeError);
+ DISALLOW_COPY_AND_ASSIGN(RuntimeError);
};
} // namespace extensions
diff --git a/extensions/common/switches.cc b/extensions/common/switches.cc
index 228a557..3c8ab10 100644
--- a/extensions/common/switches.cc
+++ b/extensions/common/switches.cc
@@ -22,6 +22,10 @@ const char kAllowScriptingGallery[] = "allow-scripting-gallery";
const char kEnableExperimentalExtensionApis[] =
"enable-experimental-extension-apis";
+// Allows the ErrorConsole to collect runtime and manifest errors, and display
+// them in the chrome:extensions page.
+const char kErrorConsole[] = "error-console";
+
// Enables extensions running scripts on chrome:// URLs.
// Extensions still need to explicitly request access to chrome:// URLs in the
// manifest.
diff --git a/extensions/common/switches.h b/extensions/common/switches.h
index 7fceb54..43cc0f1 100644
--- a/extensions/common/switches.h
+++ b/extensions/common/switches.h
@@ -14,6 +14,7 @@ namespace switches {
extern const char kAllowLegacyExtensionManifests[];
extern const char kAllowScriptingGallery[];
extern const char kEnableExperimentalExtensionApis[];
+extern const char kErrorConsole[];
extern const char kExtensionsOnChromeURLs[];
extern const char kShowComponentExtensionOptions[];