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.
4
5#ifndef EXTENSIONS_BROWSER_EXTENSION_ERROR_H_
6#define EXTENSIONS_BROWSER_EXTENSION_ERROR_H_
7
8#include <string>
9#include <vector>
10
11#include "base/compiler_specific.h"
12#include "base/logging.h"
13#include "base/memory/scoped_ptr.h"
14#include "base/strings/string16.h"
15#include "extensions/common/stack_frame.h"
16#include "url/gurl.h"
17
18namespace base {
19class DictionaryValue;
20}
21
22namespace extensions {
23
24class ExtensionError {
25 public:
26  enum Type {
27    MANIFEST_ERROR,
28    RUNTIME_ERROR
29  };
30
31  virtual ~ExtensionError();
32
33  // Serializes the ExtensionError into JSON format.
34  virtual scoped_ptr<base::DictionaryValue> ToValue() const;
35
36  virtual std::string PrintForTest() const;
37
38  // Return true if this error and |rhs| are considered equal, and should be
39  // grouped together.
40  bool IsEqual(const ExtensionError* rhs) const;
41
42  Type type() const { return type_; }
43  const std::string& extension_id() const { return extension_id_; }
44  bool from_incognito() const { return from_incognito_; }
45  logging::LogSeverity level() const { return level_; }
46  const base::string16& source() const { return source_; }
47  const base::string16& message() const { return message_; }
48  size_t occurrences() const { return occurrences_; }
49  void set_occurrences(size_t occurrences) { occurrences_ = occurrences; }
50
51  // Keys used for retrieving JSON values.
52  static const char kExtensionIdKey[];
53  static const char kFromIncognitoKey[];
54  static const char kLevelKey[];
55  static const char kMessageKey[];
56  static const char kSourceKey[];
57  static const char kTypeKey[];
58
59 protected:
60  ExtensionError(Type type,
61                 const std::string& extension_id,
62                 bool from_incognito,
63                 logging::LogSeverity level,
64                 const base::string16& source,
65                 const base::string16& message);
66
67  virtual bool IsEqualImpl(const ExtensionError* rhs) const = 0;
68
69  // Which type of error this is.
70  Type type_;
71  // The ID of the extension which caused the error.
72  std::string extension_id_;
73  // Whether or not the error was caused while incognito.
74  bool from_incognito_;
75  // The severity level of the error.
76  logging::LogSeverity level_;
77  // The source for the error; this can be a script, web page, or manifest file.
78  // This is stored as a string (rather than a url) since it can be a Chrome
79  // script file (e.g., event_bindings.js).
80  base::string16 source_;
81  // The error message itself.
82  base::string16 message_;
83  // The number of times this error has occurred.
84  size_t occurrences_;
85
86  DISALLOW_COPY_AND_ASSIGN(ExtensionError);
87};
88
89class ManifestError : public ExtensionError {
90 public:
91  ManifestError(const std::string& extension_id,
92                const base::string16& message,
93                const base::string16& manifest_key,
94                const base::string16& manifest_specific);
95  virtual ~ManifestError();
96
97  virtual scoped_ptr<base::DictionaryValue> ToValue() const OVERRIDE;
98
99  virtual std::string PrintForTest() const OVERRIDE;
100
101  const base::string16& manifest_key() const { return manifest_key_; }
102  const base::string16& manifest_specific() const { return manifest_specific_; }
103
104  // Keys used for retrieving JSON values.
105  static const char kManifestKeyKey[];
106  static const char kManifestSpecificKey[];
107
108 private:
109  virtual bool IsEqualImpl(const ExtensionError* rhs) const OVERRIDE;
110
111  // If present, this indicates the feature in the manifest which caused the
112  // error.
113  base::string16 manifest_key_;
114  // If present, this is a more-specific location of the error - for instance,
115  // a specific permission which is incorrect, rather than simply "permissions".
116  base::string16 manifest_specific_;
117
118  DISALLOW_COPY_AND_ASSIGN(ManifestError);
119};
120
121class RuntimeError : public ExtensionError {
122 public:
123  RuntimeError(const std::string& extension_id,  // optional, sometimes unknown.
124               bool from_incognito,
125               const base::string16& source,
126               const base::string16& message,
127               const StackTrace& stack_trace,
128               const GURL& context_url,
129               logging::LogSeverity level,
130               int render_view_id,
131               int render_process_id);
132  virtual ~RuntimeError();
133
134  virtual scoped_ptr<base::DictionaryValue> ToValue() const OVERRIDE;
135
136  virtual std::string PrintForTest() const OVERRIDE;
137
138  const GURL& context_url() const { return context_url_; }
139  const StackTrace& stack_trace() const { return stack_trace_; }
140  int render_view_id() const { return render_view_id_; }
141  int render_process_id() const { return render_process_id_; }
142
143  // Keys used for retrieving JSON values.
144  static const char kColumnNumberKey[];
145  static const char kContextUrlKey[];
146  static const char kFunctionNameKey[];
147  static const char kLineNumberKey[];
148  static const char kStackTraceKey[];
149  static const char kUrlKey[];
150  static const char kRenderProcessIdKey[];
151  static const char kRenderViewIdKey[];
152
153 private:
154  virtual bool IsEqualImpl(const ExtensionError* rhs) const OVERRIDE;
155
156  // Since we piggy-back onto other error reporting systems (like V8 and
157  // WebKit), the reported information may need to be cleaned up in order to be
158  // in a consistent format.
159  void CleanUpInit();
160
161  GURL context_url_;
162  StackTrace stack_trace_;
163
164  // Keep track of the render process which caused the error in order to
165  // inspect the view later, if possible.
166  int render_view_id_;
167  int render_process_id_;
168
169  DISALLOW_COPY_AND_ASSIGN(RuntimeError);
170};
171
172}  // namespace extensions
173
174#endif  // EXTENSIONS_BROWSER_EXTENSION_ERROR_H_
175