| OLD | NEW | 
|    1 // Copyright 2013 The Chromium Authors. All rights reserved. |    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 |    2 // Use of this source code is governed by a BSD-style license that can be | 
|    3 // found in the LICENSE file. |    3 // found in the LICENSE file. | 
|    4  |    4  | 
|    5 #include "extensions/browser/extension_error.h" |    5 #include "extensions/browser/extension_error.h" | 
|    6  |    6  | 
|    7 #include "base/json/json_reader.h" |  | 
|    8 #include "base/strings/string_number_conversions.h" |    7 #include "base/strings/string_number_conversions.h" | 
|    9 #include "base/strings/utf_string_conversions.h" |    8 #include "base/strings/utf_string_conversions.h" | 
|   10 #include "base/values.h" |    9 #include "base/values.h" | 
|   11 #include "extensions/common/constants.h" |   10 #include "extensions/common/constants.h" | 
|   12 #include "url/gurl.h" |   11 #include "url/gurl.h" | 
|   13  |   12  | 
|   14 using base::string16; |   13 using base::string16; | 
|   15  |   14  | 
|   16 namespace extensions { |   15 namespace extensions { | 
|   17  |   16  | 
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   90   return ExtensionError::PrintForTest() + |   89   return ExtensionError::PrintForTest() + | 
|   91          "\n  Type:    ManifestError"; |   90          "\n  Type:    ManifestError"; | 
|   92 } |   91 } | 
|   93  |   92  | 
|   94 bool ManifestError::IsEqualImpl(const ExtensionError* rhs) const { |   93 bool ManifestError::IsEqualImpl(const ExtensionError* rhs) const { | 
|   95   // If two manifest errors have the same extension id and message (which are |   94   // If two manifest errors have the same extension id and message (which are | 
|   96   // both checked in ExtensionError::IsEqual), then they are equal. |   95   // both checked in ExtensionError::IsEqual), then they are equal. | 
|   97   return true; |   96   return true; | 
|   98 } |   97 } | 
|   99  |   98  | 
|  100 RuntimeError::StackFrame::StackFrame() : line_number(-1), column_number(-1) { |  | 
|  101 } |  | 
|  102  |  | 
|  103 RuntimeError::StackFrame::StackFrame(size_t frame_line, |  | 
|  104                                      size_t frame_column, |  | 
|  105                                      const string16& frame_url, |  | 
|  106                                      const string16& frame_function) |  | 
|  107     : line_number(frame_line), |  | 
|  108       column_number(frame_column), |  | 
|  109       url(frame_url), |  | 
|  110       function(frame_function) { |  | 
|  111 } |  | 
|  112  |  | 
|  113 RuntimeError::StackFrame::~StackFrame() { |  | 
|  114 } |  | 
|  115  |  | 
|  116 bool RuntimeError::StackFrame::operator==( |  | 
|  117     const RuntimeError::StackFrame& rhs) const { |  | 
|  118   return line_number == rhs.line_number && |  | 
|  119          column_number == rhs.column_number && |  | 
|  120          url == rhs.url && |  | 
|  121          function == rhs.function; |  | 
|  122 } |  | 
|  123 RuntimeError::RuntimeError(bool from_incognito, |   99 RuntimeError::RuntimeError(bool from_incognito, | 
|  124                            const string16& source, |  100                            const string16& source, | 
|  125                            const string16& message, |  101                            const string16& message, | 
|  126                            logging::LogSeverity level, |  102                            const StackTrace& stack_trace, | 
|  127                            const string16& details) |  103                            const GURL& context_url, | 
 |  104                            logging::LogSeverity level) | 
|  128     : ExtensionError(ExtensionError::RUNTIME_ERROR, |  105     : ExtensionError(ExtensionError::RUNTIME_ERROR, | 
|  129                      std::string(),  // We don't know the id yet. |  106                      GURL(source).host(), | 
|  130                      from_incognito, |  107                      from_incognito, | 
|  131                      level, |  108                      level, | 
|  132                      source, |  109                      source, | 
|  133                      message) { |  110                      message), | 
|  134   ParseDetails(details); |  111       context_url_(context_url), | 
|  135   DetermineExtensionID(); |  112       stack_trace_(stack_trace) { | 
 |  113   CleanUpInit(); | 
|  136 } |  114 } | 
|  137  |  115  | 
|  138 RuntimeError::~RuntimeError() { |  116 RuntimeError::~RuntimeError() { | 
|  139 } |  117 } | 
|  140  |  118  | 
|  141 std::string RuntimeError::PrintForTest() const { |  119 std::string RuntimeError::PrintForTest() const { | 
|  142   std::string result = ExtensionError::PrintForTest() + |  120   std::string result = ExtensionError::PrintForTest() + | 
|  143          "\n  Type:    RuntimeError" |  121          "\n  Type:    RuntimeError" | 
|  144          "\n  Context: " + base::UTF16ToUTF8(execution_context_url_) + |  122          "\n  Context: " + context_url_.spec() + | 
|  145          "\n  Stack Trace: "; |  123          "\n  Stack Trace: "; | 
|  146   for (StackTrace::const_iterator iter = stack_trace_.begin(); |  124   for (StackTrace::const_iterator iter = stack_trace_.begin(); | 
|  147        iter != stack_trace_.end(); ++iter) { |  125        iter != stack_trace_.end(); ++iter) { | 
|  148     result += "\n    {" |  126     result += "\n    {" | 
|  149               "\n      Line:     " + base::IntToString(iter->line_number) + |  127               "\n      Line:     " + base::IntToString(iter->line_number) + | 
|  150               "\n      Column:   " + base::IntToString(iter->column_number) + |  128               "\n      Column:   " + base::IntToString(iter->column_number) + | 
|  151               "\n      URL:      " + base::UTF16ToUTF8(iter->url) + |  129               "\n      URL:      " + base::UTF16ToUTF8(iter->source) + | 
|  152               "\n      Function: " + base::UTF16ToUTF8(iter->function) + |  130               "\n      Function: " + base::UTF16ToUTF8(iter->function) + | 
|  153               "\n    }"; |  131               "\n    }"; | 
|  154   } |  132   } | 
|  155   return result; |  133   return result; | 
|  156 } |  134 } | 
|  157  |  135  | 
|  158 bool RuntimeError::IsEqualImpl(const ExtensionError* rhs) const { |  136 bool RuntimeError::IsEqualImpl(const ExtensionError* rhs) const { | 
|  159   const RuntimeError* error = static_cast<const RuntimeError*>(rhs); |  137   const RuntimeError* error = static_cast<const RuntimeError*>(rhs); | 
|  160  |  138  | 
|  161   // Only look at the first frame of a stack trace to save time and group |  139   // Only look at the first frame of a stack trace to save time and group | 
|  162   // nearly-identical errors. The most recent error is kept, so there's no risk |  140   // nearly-identical errors. The most recent error is kept, so there's no risk | 
|  163   // of displaying an old and inaccurate stack trace. |  141   // of displaying an old and inaccurate stack trace. | 
|  164   return level_ == level_ && |  142   return level_ == level_ && | 
|  165          source_ == source_ && |  143          source_ == source_ && | 
|  166          execution_context_url_ == error->execution_context_url_ && |  144          context_url_ == error->context_url_ && | 
|  167          stack_trace_.size() == error->stack_trace_.size() && |  145          stack_trace_.size() == error->stack_trace_.size() && | 
|  168          (stack_trace_.empty() || stack_trace_[0] == error->stack_trace_[0]); |  146          (stack_trace_.empty() || stack_trace_[0] == error->stack_trace_[0]); | 
|  169 } |  147 } | 
|  170  |  148  | 
|  171 void RuntimeError::ParseDetails(const string16& details) { |  149 void RuntimeError::CleanUpInit() { | 
|  172   scoped_ptr<base::Value> value( |  150   // If the error came from a generated background page, the "context" is empty | 
|  173       base::JSONReader::Read(base::UTF16ToUTF8(details))); |  151   // because there's no visible URL. We should set context to be the generated | 
|  174   const base::DictionaryValue* details_value; |  152   // background page in this case. | 
|  175   const base::ListValue* trace_value = NULL; |  153   GURL source_url = GURL(source_); | 
|  176  |  154   if (context_url_.is_empty() && | 
|  177   // The |details| value should contain an execution context url and a stack |  155       source_url.path() == | 
|  178   // trace. |  156           std::string("/") + kGeneratedBackgroundPageFilename) { | 
|  179   if (!value.get() || |  157     context_url_ = source_url; | 
|  180       !value->GetAsDictionary(&details_value) || |  | 
|  181       !details_value->GetString(kExecutionContextURLKey, |  | 
|  182                                 &execution_context_url_) || |  | 
|  183       !details_value->GetList(kStackTraceKey, &trace_value)) { |  | 
|  184     NOTREACHED(); |  | 
|  185     return; |  | 
|  186   } |  158   } | 
|  187  |  159  | 
|  188   int line = 0; |  160   // In some instances (due to the fact that we're reusing error reporting from | 
|  189   int column = 0; |  161   // other systems), the source won't match up with the final entry in the stack | 
|  190   string16 url; |  162   // trace. (For instance, in a browser action error, the source is the page - | 
|  191  |  163   // sometimes the background page - but the error is thrown from the script.) | 
|  192   for (size_t i = 0; i < trace_value->GetSize(); ++i) { |  164   // Make the source match the stack trace, since that is more likely the cause | 
|  193     const base::DictionaryValue* frame_value = NULL; |  165   // of the error. | 
|  194     CHECK(trace_value->GetDictionary(i, &frame_value)); |  166   if (!stack_trace_.empty() && source_ != stack_trace_[0].source) | 
|  195  |  167     source_ = stack_trace_[0].source; | 
|  196     frame_value->GetInteger(kLineNumberKey, &line); |  | 
|  197     frame_value->GetInteger(kColumnNumberKey, &column); |  | 
|  198     frame_value->GetString(kURLKey, &url); |  | 
|  199  |  | 
|  200     string16 function; |  | 
|  201     frame_value->GetString(kFunctionNameKey, &function);  // This can be empty. |  | 
|  202     stack_trace_.push_back(StackFrame(line, column, url, function)); |  | 
|  203   } |  | 
|  204 } |  | 
|  205  |  | 
|  206 void RuntimeError::DetermineExtensionID() { |  | 
|  207   if (!GetExtensionIDFromGURL(GURL(source_), &extension_id_)) |  | 
|  208     GetExtensionIDFromGURL(GURL(execution_context_url_), &extension_id_); |  | 
|  209 } |  168 } | 
|  210  |  169  | 
|  211 }  // namespace extensions |  170 }  // namespace extensions | 
| OLD | NEW |