1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef mozilla_dom_DOMException_h__
8 #define mozilla_dom_DOMException_h__
9 
10 // We intentionally shadow non-virtual methods, but gcc gets confused.
11 #ifdef __GNUC__
12 #  pragma GCC diagnostic push
13 #  pragma GCC diagnostic ignored "-Woverloaded-virtual"
14 #endif
15 
16 #include <stdint.h>
17 #include "js/Value.h"
18 #include "jspubtd.h"
19 #include "nsCOMPtr.h"
20 #include "nsCycleCollectionParticipant.h"
21 #include "nsID.h"
22 #include "nsWrapperCache.h"
23 #include "nsIException.h"
24 #include "nsString.h"
25 #include "mozilla/dom/BindingDeclarations.h"
26 
27 class nsIStackFrame;
28 
29 nsresult NS_GetNameAndMessageForDOMNSResult(nsresult aNSResult,
30                                             nsACString& aName,
31                                             nsACString& aMessage,
32                                             uint16_t* aCode = nullptr);
33 
34 namespace mozilla {
35 class ErrorResult;
36 
37 namespace dom {
38 
39 class GlobalObject;
40 
41 #define MOZILLA_EXCEPTION_IID                        \
42   {                                                  \
43     0x55eda557, 0xeba0, 0x4fe3, {                    \
44       0xae, 0x2e, 0xf3, 0x94, 0x49, 0x23, 0x62, 0xd6 \
45     }                                                \
46   }
47 
48 class Exception : public nsIException, public nsWrapperCache {
49  public:
NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_EXCEPTION_IID)50   NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_EXCEPTION_IID)
51 
52   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Exception)
53 
54   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
55   NS_DECL_NSIEXCEPTION
56 
57   const nsCString& GetMessageMoz() const { return mMessage; }
GetResult()58   nsresult GetResult() const { return mResult; }
59   // DOMException wants different ToString behavior, so allow it to override.
60   virtual void ToString(JSContext* aCx, nsACString& aReturn);
61 
62   // Cruft used by XPConnect for exceptions originating in JS implemented
63   // components.
64   bool StealJSVal(JS::Value* aVp);
65   void StowJSVal(JS::Value& aVp);
66 
67   // WebIDL API
68   virtual JSObject* WrapObject(JSContext* cx,
69                                JS::Handle<JSObject*> aGivenProto) override;
70 
GetParentObject()71   nsISupports* GetParentObject() const { return nullptr; }
72 
73   void GetMessageMoz(nsString& retval);
74 
75   uint32_t Result() const;
76 
77   void GetName(nsAString& retval);
78 
GetErrorMessage(nsAString & aRetVal)79   virtual void GetErrorMessage(nsAString& aRetVal) {
80     // Since GetName is non non-virtual and deals with different
81     // member variables in Exception vs. DOMException, have a virtual
82     // method to ensure the right error message creation.
83     nsAutoString name;
84     GetName(name);
85     CreateErrorMessage(name, aRetVal);
86   }
87 
88   void GetFilename(JSContext* aCx, nsAString& aFilename);
89 
90   uint32_t SourceId(JSContext* aCx) const;
91 
92   uint32_t LineNumber(JSContext* aCx) const;
93 
94   uint32_t ColumnNumber() const;
95 
96   already_AddRefed<nsIStackFrame> GetLocation() const;
97 
98   nsISupports* GetData() const;
99 
100   void GetStack(JSContext* aCx, nsAString& aStack) const;
101 
102   void Stringify(JSContext* aCx, nsString& retval);
103 
104   Exception(const nsACString& aMessage, nsresult aResult,
105             const nsACString& aName, nsIStackFrame* aLocation,
106             nsISupports* aData);
107 
108  protected:
109   virtual ~Exception();
110 
CreateErrorMessage(const nsAString & aName,nsAString & aRetVal)111   void CreateErrorMessage(const nsAString& aName, nsAString& aRetVal) {
112     // Create similar error message as what ErrorReport::init does in jsexn.cpp.
113     if (!aName.IsEmpty() && !mMessage.IsEmpty()) {
114       aRetVal.Assign(aName);
115       aRetVal.AppendLiteral(": ");
116       AppendUTF8toUTF16(mMessage, aRetVal);
117     } else if (!aName.IsEmpty()) {
118       aRetVal.Assign(aName);
119     } else if (!mMessage.IsEmpty()) {
120       CopyUTF8toUTF16(mMessage, aRetVal);
121     } else {
122       aRetVal.Truncate();
123     }
124   }
125 
126   nsCString mMessage;
127   nsresult mResult;
128   nsCString mName;
129   nsCOMPtr<nsIStackFrame> mLocation;
130   nsCOMPtr<nsISupports> mData;
131 
132   bool mHoldingJSVal;
133   JS::Heap<JS::Value> mThrownJSVal;
134 };
135 
NS_DEFINE_STATIC_IID_ACCESSOR(Exception,MOZILLA_EXCEPTION_IID)136 NS_DEFINE_STATIC_IID_ACCESSOR(Exception, MOZILLA_EXCEPTION_IID)
137 
138 class DOMException : public Exception {
139  public:
140   DOMException(nsresult aRv, const nsACString& aMessage,
141                const nsACString& aName, uint16_t aCode,
142                nsIStackFrame* aLocation = nullptr);
143 
144   NS_INLINE_DECL_REFCOUNTING_INHERITED(DOMException, Exception)
145 
146   // nsWrapperCache overrides
147   virtual JSObject* WrapObject(JSContext* aCx,
148                                JS::Handle<JSObject*> aGivenProto) override;
149 
150   static already_AddRefed<DOMException> Constructor(
151       GlobalObject& /* unused */, const nsAString& aMessage,
152       const Optional<nsAString>& aName);
153 
154   uint16_t Code() const { return mCode; }
155 
156   // Intentionally shadow the Exception version.
157   void GetName(nsString& retval);
158 
159   // Exception overrides
160   void ToString(JSContext* aCx, nsACString& aReturn) override;
161 
162   virtual void GetErrorMessage(nsAString& aRetVal) override {
163     // See the comment in Exception::GetErrorMessage.
164     nsAutoString name;
165     GetName(name);
166     CreateErrorMessage(name, aRetVal);
167   }
168 
169   static already_AddRefed<DOMException> Create(nsresult aRv);
170 
171   static already_AddRefed<DOMException> Create(nsresult aRv,
172                                                const nsACString& aMessage);
173 
174  protected:
175   virtual ~DOMException() = default;
176 
177   uint16_t mCode;
178 };
179 
180 }  // namespace dom
181 }  // namespace mozilla
182 
183 #ifdef __GNUC__
184 #  pragma GCC diagnostic pop
185 #endif
186 
187 #endif
188