1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 1998
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Pierre Phaneuf <pp@ludusdesign.com>
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either of the GNU General Public License Version 2 or later (the "GPL"),
27 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : #include "nsCOMPtr.h"
40 : #include "nsCRTGlue.h"
41 : #include "nsDOMClassInfoID.h"
42 : #include "nsDOMError.h"
43 : #include "nsDOMException.h"
44 : #include "nsIDOMDOMException.h"
45 : #include "nsIDOMFileException.h"
46 : #include "nsIDOMSVGException.h"
47 : #include "nsIDOMXPathException.h"
48 : #include "nsIIDBDatabaseException.h"
49 : #include "nsString.h"
50 : #include "prprf.h"
51 :
52 : #define DOM_MSG_DEF(val, message) {(val), #val, message},
53 : #define DOM_MSG_DEF_(val, name, message) {(NS_ERROR_DOM_##val), name, message},
54 :
55 : #define IMPL_INTERNAL_DOM_EXCEPTION_HEAD(classname, ifname) \
56 : class classname : public nsBaseDOMException, \
57 : public ifname \
58 : { \
59 : public: \
60 : classname(); \
61 : virtual ~classname(); \
62 : \
63 : NS_DECL_ISUPPORTS_INHERITED
64 :
65 : #define IMPL_INTERNAL_DOM_EXCEPTION_TAIL(classname, ifname, domname, module, \
66 : mapping_function) \
67 : }; \
68 : \
69 : classname::classname() {} \
70 : classname::~classname() {} \
71 : \
72 : DOMCI_DATA(domname, classname) \
73 : \
74 : NS_IMPL_ADDREF_INHERITED(classname, nsBaseDOMException) \
75 : NS_IMPL_RELEASE_INHERITED(classname, nsBaseDOMException) \
76 : NS_INTERFACE_MAP_BEGIN(classname) \
77 : NS_INTERFACE_MAP_ENTRY(ifname) \
78 : NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(domname) \
79 : NS_INTERFACE_MAP_END_INHERITING(nsBaseDOMException) \
80 : \
81 : nsresult \
82 : NS_New##domname(nsresult aNSResult, nsIException* aDefaultException, \
83 : nsIException** aException) \
84 : { \
85 : if (!(NS_ERROR_GET_MODULE(aNSResult) == module)) { \
86 : NS_WARNING("Trying to create an exception for the wrong error module."); \
87 : return NS_ERROR_FAILURE; \
88 : } \
89 : const char* name; \
90 : const char* message; \
91 : mapping_function(aNSResult, &name, &message); \
92 : classname* inst = new classname(); \
93 : NS_ENSURE_TRUE(inst, NS_ERROR_OUT_OF_MEMORY); \
94 : inst->Init(aNSResult, name, message, aDefaultException); \
95 : *aException = inst; \
96 : NS_ADDREF(*aException); \
97 : return NS_OK; \
98 : }
99 :
100 : static struct ResultStruct
101 : {
102 : nsresult mNSResult;
103 : const char* mName;
104 : const char* mMessage;
105 : } gDOMErrorMsgMap[] = {
106 : #include "domerr.msg"
107 : {0, nsnull, nsnull} // sentinel to mark end of array
108 : };
109 :
110 : #undef DOM_MSG_DEF
111 : #undef DOM_MSG_DEF_
112 :
113 : static void
114 207 : NSResultToNameAndMessage(nsresult aNSResult,
115 : const char** aName,
116 : const char** aMessage)
117 : {
118 207 : *aName = nsnull;
119 207 : *aMessage = nsnull;
120 207 : ResultStruct* result_struct = gDOMErrorMsgMap;
121 :
122 7387 : while (result_struct->mName) {
123 7180 : if (aNSResult == result_struct->mNSResult) {
124 207 : *aName = result_struct->mName;
125 207 : *aMessage = result_struct->mMessage;
126 207 : return;
127 : }
128 :
129 6973 : ++result_struct;
130 : }
131 :
132 0 : NS_WARNING("Huh, someone is throwing non-DOM errors using the DOM module!");
133 :
134 0 : return;
135 : }
136 :
137 : nsresult
138 0 : NS_GetNameAndMessageForDOMNSResult(nsresult aNSResult, const char** aName,
139 : const char** aMessage)
140 : {
141 0 : const char* name = nsnull;
142 0 : const char* message = nsnull;
143 0 : NSResultToNameAndMessage(aNSResult, &name, &message);
144 :
145 0 : if (name && message) {
146 0 : *aName = name;
147 0 : *aMessage = message;
148 0 : return NS_OK;
149 : }
150 :
151 0 : return NS_ERROR_NOT_AVAILABLE;
152 : }
153 :
154 : IMPL_INTERNAL_DOM_EXCEPTION_HEAD(nsDOMException, nsIDOMDOMException)
155 : NS_DECL_NSIDOMDOMEXCEPTION
156 88 : IMPL_INTERNAL_DOM_EXCEPTION_TAIL(nsDOMException, nsIDOMDOMException,
157 : DOMException, NS_ERROR_MODULE_DOM,
158 4 : NSResultToNameAndMessage)
159 :
160 : NS_IMETHODIMP
161 0 : nsDOMException::GetCode(PRUint16* aCode)
162 : {
163 0 : NS_ENSURE_ARG_POINTER(aCode);
164 : nsresult result;
165 0 : GetResult(&result);
166 0 : *aCode = NS_ERROR_GET_CODE(result);
167 :
168 0 : return NS_OK;
169 : }
170 :
171 : IMPL_INTERNAL_DOM_EXCEPTION_HEAD(nsSVGException, nsIDOMSVGException)
172 : NS_DECL_NSIDOMSVGEXCEPTION
173 0 : IMPL_INTERNAL_DOM_EXCEPTION_TAIL(nsSVGException, nsIDOMSVGException,
174 : SVGException, NS_ERROR_MODULE_SVG,
175 0 : NSResultToNameAndMessage)
176 :
177 : NS_IMETHODIMP
178 0 : nsSVGException::GetCode(PRUint16* aCode)
179 : {
180 0 : NS_ENSURE_ARG_POINTER(aCode);
181 : nsresult result;
182 0 : GetResult(&result);
183 0 : *aCode = NS_ERROR_GET_CODE(result);
184 :
185 0 : return NS_OK;
186 : }
187 :
188 : IMPL_INTERNAL_DOM_EXCEPTION_HEAD(nsXPathException, nsIDOMXPathException)
189 : NS_DECL_NSIDOMXPATHEXCEPTION
190 0 : IMPL_INTERNAL_DOM_EXCEPTION_TAIL(nsXPathException, nsIDOMXPathException,
191 : XPathException, NS_ERROR_MODULE_DOM_XPATH,
192 0 : NSResultToNameAndMessage)
193 :
194 : NS_IMETHODIMP
195 0 : nsXPathException::GetCode(PRUint16* aCode)
196 : {
197 0 : NS_ENSURE_ARG_POINTER(aCode);
198 : nsresult result;
199 0 : GetResult(&result);
200 0 : *aCode = NS_ERROR_GET_CODE(result);
201 :
202 0 : return NS_OK;
203 : }
204 :
205 : IMPL_INTERNAL_DOM_EXCEPTION_HEAD(nsDOMFileException, nsIDOMFileException)
206 : NS_DECL_NSIDOMFILEEXCEPTION
207 0 : IMPL_INTERNAL_DOM_EXCEPTION_TAIL(nsDOMFileException, nsIDOMFileException,
208 : FileException, NS_ERROR_MODULE_DOM_FILE,
209 0 : NSResultToNameAndMessage)
210 :
211 : NS_IMETHODIMP
212 0 : nsDOMFileException::GetCode(PRUint16* aCode)
213 : {
214 0 : NS_ENSURE_ARG_POINTER(aCode);
215 : nsresult result;
216 0 : GetResult(&result);
217 0 : *aCode = NS_ERROR_GET_CODE(result);
218 :
219 0 : return NS_OK;
220 : }
221 :
222 : IMPL_INTERNAL_DOM_EXCEPTION_HEAD(nsIDBDatabaseException,
223 : nsIIDBDatabaseException)
224 : NS_DECL_NSIIDBDATABASEEXCEPTION
225 5146 : IMPL_INTERNAL_DOM_EXCEPTION_TAIL(nsIDBDatabaseException,
226 : nsIIDBDatabaseException,
227 : IDBDatabaseException,
228 : NS_ERROR_MODULE_DOM_INDEXEDDB,
229 203 : NSResultToNameAndMessage)
230 :
231 : NS_IMETHODIMP
232 170 : nsIDBDatabaseException::GetCode(PRUint16* aCode)
233 : {
234 170 : NS_ASSERTION(aCode, "Null pointer!");
235 : nsresult result;
236 170 : GetResult(&result);
237 170 : *aCode = NS_ERROR_GET_CODE(result);
238 170 : return NS_OK;
239 : }
240 :
241 207 : nsBaseDOMException::nsBaseDOMException()
242 : {
243 207 : }
244 :
245 207 : nsBaseDOMException::~nsBaseDOMException()
246 : {
247 414 : }
248 :
249 3408 : NS_IMPL_ISUPPORTS2(nsBaseDOMException, nsIException, nsIBaseDOMException)
250 :
251 : NS_IMETHODIMP
252 0 : nsBaseDOMException::GetMessageMoz(char **aMessage)
253 : {
254 0 : if (mMessage) {
255 0 : *aMessage = NS_strdup(mMessage);
256 : } else {
257 0 : *aMessage = nsnull;
258 : }
259 :
260 0 : return NS_OK;
261 : }
262 :
263 : NS_IMETHODIMP
264 171 : nsBaseDOMException::GetResult(PRUint32* aResult)
265 : {
266 171 : NS_ENSURE_ARG_POINTER(aResult);
267 :
268 171 : *aResult = mResult;
269 :
270 171 : return NS_OK;
271 : }
272 :
273 : NS_IMETHODIMP
274 0 : nsBaseDOMException::GetName(char **aName)
275 : {
276 0 : NS_ENSURE_ARG_POINTER(aName);
277 :
278 0 : if (mName) {
279 0 : *aName = NS_strdup(mName);
280 : } else {
281 0 : *aName = nsnull;
282 : }
283 :
284 0 : return NS_OK;
285 : }
286 :
287 : NS_IMETHODIMP
288 0 : nsBaseDOMException::GetFilename(char **aFilename)
289 : {
290 0 : if (mInner) {
291 0 : return mInner->GetFilename(aFilename);
292 : }
293 :
294 0 : NS_ENSURE_ARG_POINTER(aFilename);
295 :
296 0 : *aFilename = nsnull;
297 :
298 0 : return NS_OK;
299 : }
300 :
301 : NS_IMETHODIMP
302 0 : nsBaseDOMException::GetLineNumber(PRUint32 *aLineNumber)
303 : {
304 0 : if (mInner) {
305 0 : return mInner->GetLineNumber(aLineNumber);
306 : }
307 :
308 0 : NS_ENSURE_ARG_POINTER(aLineNumber);
309 :
310 0 : *aLineNumber = 0;
311 :
312 0 : return NS_OK;
313 : }
314 :
315 : NS_IMETHODIMP
316 0 : nsBaseDOMException::GetColumnNumber(PRUint32 *aColumnNumber)
317 : {
318 0 : if (mInner) {
319 0 : return mInner->GetColumnNumber(aColumnNumber);
320 : }
321 :
322 0 : NS_ENSURE_ARG_POINTER(aColumnNumber);
323 :
324 0 : *aColumnNumber = 0;
325 :
326 0 : return NS_OK;
327 : }
328 :
329 : NS_IMETHODIMP
330 0 : nsBaseDOMException::GetLocation(nsIStackFrame **aLocation)
331 : {
332 0 : if (mInner) {
333 0 : return mInner->GetLocation(aLocation);
334 : }
335 :
336 0 : NS_ENSURE_ARG_POINTER(aLocation);
337 :
338 0 : *aLocation = nsnull;
339 :
340 0 : return NS_OK;
341 : }
342 :
343 : NS_IMETHODIMP
344 0 : nsBaseDOMException::GetInner(nsIException **aInner)
345 : {
346 0 : NS_ENSURE_ARG_POINTER(aInner);
347 :
348 0 : *aInner = nsnull;
349 :
350 0 : return NS_OK;
351 : }
352 :
353 : NS_IMETHODIMP
354 0 : nsBaseDOMException::GetData(nsISupports **aData)
355 : {
356 0 : if (mInner) {
357 0 : return mInner->GetData(aData);
358 : }
359 :
360 0 : NS_ENSURE_ARG_POINTER(aData);
361 :
362 0 : *aData = nsnull;
363 :
364 0 : return NS_OK;
365 : }
366 :
367 : NS_IMETHODIMP
368 0 : nsBaseDOMException::ToString(char **aReturn)
369 : {
370 0 : *aReturn = nsnull;
371 :
372 : static const char defaultMsg[] = "<no message>";
373 : static const char defaultLocation[] = "<unknown>";
374 : static const char defaultName[] = "<unknown>";
375 : static const char format[] =
376 : "[Exception... \"%s\" code: \"%d\" nsresult: \"0x%x (%s)\" location: \"%s\"]";
377 :
378 0 : nsCAutoString location;
379 :
380 0 : if (mInner) {
381 0 : nsXPIDLCString filename;
382 :
383 0 : mInner->GetFilename(getter_Copies(filename));
384 :
385 0 : if (!filename.IsEmpty()) {
386 0 : PRUint32 line_nr = 0;
387 :
388 0 : mInner->GetLineNumber(&line_nr);
389 :
390 0 : char *temp = PR_smprintf("%s Line: %d", filename.get(), line_nr);
391 0 : if (temp) {
392 0 : location.Assign(temp);
393 0 : PR_smprintf_free(temp);
394 : }
395 : }
396 : }
397 :
398 0 : if (location.IsEmpty()) {
399 0 : location = defaultLocation;
400 : }
401 :
402 0 : const char* msg = mMessage ? mMessage : defaultMsg;
403 0 : const char* resultName = mName ? mName : defaultName;
404 0 : PRUint32 code = NS_ERROR_GET_CODE(mResult);
405 :
406 : *aReturn = PR_smprintf(format, msg, code, mResult, resultName,
407 0 : location.get());
408 :
409 0 : return *aReturn ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
410 : }
411 :
412 : NS_IMETHODIMP
413 207 : nsBaseDOMException::Init(nsresult aNSResult, const char* aName,
414 : const char* aMessage,
415 : nsIException* aDefaultException)
416 : {
417 207 : mResult = aNSResult;
418 207 : mName = aName;
419 207 : mMessage = aMessage;
420 207 : mInner = aDefaultException;
421 207 : return NS_OK;
422 : }
|