diff options
author | rdevlin.cronin@chromium.org <rdevlin.cronin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-28 21:59:23 +0000 |
---|---|---|
committer | rdevlin.cronin@chromium.org <rdevlin.cronin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-28 21:59:23 +0000 |
commit | d466f7818d5f44765b6fe153214306e3b6d8be8e (patch) | |
tree | af1e77ee7b54e7142323bce8f780cf606ebe3aa6 /extensions | |
parent | d9ca99e79006906b12f23b33bbb6341259ae3055 (diff) | |
download | chromium_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.cc | 93 | ||||
-rw-r--r-- | extensions/browser/extension_error.h | 56 | ||||
-rw-r--r-- | extensions/common/switches.cc | 4 | ||||
-rw-r--r-- | extensions/common/switches.h | 1 |
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[]; |