Line data Source code
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 : #include "mozilla/dom/DOMException.h"
8 :
9 : #include "jsprf.h"
10 : #include "mozilla/ArrayUtils.h"
11 : #include "mozilla/HoldDropJSObjects.h"
12 : #include "mozilla/dom/Exceptions.h"
13 : #include "nsContentUtils.h"
14 : #include "nsCOMPtr.h"
15 : #include "nsIClassInfoImpl.h"
16 : #include "nsIDocument.h"
17 : #include "nsIDOMDOMException.h"
18 : #include "nsIException.h"
19 : #include "nsIProgrammingLanguage.h"
20 : #include "nsMemory.h"
21 : #include "xpcprivate.h"
22 :
23 : #include "mozilla/dom/DOMExceptionBinding.h"
24 : #include "mozilla/ErrorResult.h"
25 :
26 : using namespace mozilla;
27 :
28 : enum DOM4ErrorTypeCodeMap {
29 : /* DOM4 errors from http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#domexception */
30 : IndexSizeError = nsIDOMDOMException::INDEX_SIZE_ERR,
31 : HierarchyRequestError = nsIDOMDOMException::HIERARCHY_REQUEST_ERR,
32 : WrongDocumentError = nsIDOMDOMException::WRONG_DOCUMENT_ERR,
33 : InvalidCharacterError = nsIDOMDOMException::INVALID_CHARACTER_ERR,
34 : NoModificationAllowedError = nsIDOMDOMException::NO_MODIFICATION_ALLOWED_ERR,
35 : NotFoundError = nsIDOMDOMException::NOT_FOUND_ERR,
36 : NotSupportedError = nsIDOMDOMException::NOT_SUPPORTED_ERR,
37 : // Can't remove until setNamedItem is removed
38 : InUseAttributeError = nsIDOMDOMException::INUSE_ATTRIBUTE_ERR,
39 : InvalidStateError = nsIDOMDOMException::INVALID_STATE_ERR,
40 : SyntaxError = nsIDOMDOMException::SYNTAX_ERR,
41 : InvalidModificationError = nsIDOMDOMException::INVALID_MODIFICATION_ERR,
42 : NamespaceError = nsIDOMDOMException::NAMESPACE_ERR,
43 : InvalidAccessError = nsIDOMDOMException::INVALID_ACCESS_ERR,
44 : TypeMismatchError = nsIDOMDOMException::TYPE_MISMATCH_ERR,
45 : SecurityError = nsIDOMDOMException::SECURITY_ERR,
46 : NetworkError = nsIDOMDOMException::NETWORK_ERR,
47 : AbortError = nsIDOMDOMException::ABORT_ERR,
48 : URLMismatchError = nsIDOMDOMException::URL_MISMATCH_ERR,
49 : QuotaExceededError = nsIDOMDOMException::QUOTA_EXCEEDED_ERR,
50 : TimeoutError = nsIDOMDOMException::TIMEOUT_ERR,
51 : InvalidNodeTypeError = nsIDOMDOMException::INVALID_NODE_TYPE_ERR,
52 : DataCloneError = nsIDOMDOMException::DATA_CLONE_ERR,
53 : InvalidPointerId = nsIDOMDOMException::INVALID_POINTER_ERR,
54 : EncodingError = 0,
55 :
56 : /* XXX Should be JavaScript native errors */
57 : TypeError = 0,
58 : RangeError = 0,
59 :
60 : /* IndexedDB errors http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#exceptions */
61 : UnknownError = 0,
62 : ConstraintError = 0,
63 : DataError = 0,
64 : TransactionInactiveError = 0,
65 : ReadOnlyError = 0,
66 : VersionError = 0,
67 :
68 : /* File API errors http://dev.w3.org/2006/webapi/FileAPI/#ErrorAndException */
69 : NotReadableError = 0,
70 :
71 : /* FileHandle API errors */
72 : FileHandleInactiveError = 0,
73 :
74 : /* WebCrypto errors https://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html#dfn-DataError */
75 : OperationError = 0,
76 :
77 : /* Push API errors */
78 : NotAllowedError = 0,
79 : };
80 :
81 : #define DOM4_MSG_DEF(name, message, nsresult) {(nsresult), name, #name, message},
82 : #define DOM_MSG_DEF(val, message) {(val), NS_ERROR_GET_CODE(val), #val, message},
83 :
84 : static constexpr struct ResultStruct
85 : {
86 : nsresult mNSResult;
87 : uint16_t mCode;
88 : const char* mName;
89 : const char* mMessage;
90 : } sDOMErrorMsgMap[] = {
91 : #include "domerr.msg"
92 : };
93 :
94 : #undef DOM4_MSG_DEF
95 : #undef DOM_MSG_DEF
96 :
97 : static void
98 0 : NSResultToNameAndMessage(nsresult aNSResult,
99 : nsCString& aName,
100 : nsCString& aMessage,
101 : uint16_t* aCode)
102 : {
103 0 : aName.Truncate();
104 0 : aMessage.Truncate();
105 0 : *aCode = 0;
106 0 : for (uint32_t idx = 0; idx < ArrayLength(sDOMErrorMsgMap); idx++) {
107 0 : if (aNSResult == sDOMErrorMsgMap[idx].mNSResult) {
108 0 : aName.Rebind(sDOMErrorMsgMap[idx].mName,
109 0 : strlen(sDOMErrorMsgMap[idx].mName));
110 0 : aMessage.Rebind(sDOMErrorMsgMap[idx].mMessage,
111 0 : strlen(sDOMErrorMsgMap[idx].mMessage));
112 0 : *aCode = sDOMErrorMsgMap[idx].mCode;
113 0 : return;
114 : }
115 : }
116 :
117 0 : NS_WARNING("Huh, someone is throwing non-DOM errors using the DOM module!");
118 :
119 0 : return;
120 : }
121 :
122 : nsresult
123 0 : NS_GetNameAndMessageForDOMNSResult(nsresult aNSResult, nsACString& aName,
124 : nsACString& aMessage, uint16_t* aCode)
125 : {
126 0 : nsCString name;
127 0 : nsCString message;
128 0 : uint16_t code = 0;
129 0 : NSResultToNameAndMessage(aNSResult, name, message, &code);
130 :
131 0 : if (!name.IsEmpty() && !message.IsEmpty()) {
132 0 : aName = name;
133 0 : aMessage = message;
134 0 : if (aCode) {
135 0 : *aCode = code;
136 : }
137 0 : return NS_OK;
138 : }
139 :
140 0 : return NS_ERROR_NOT_AVAILABLE;
141 : }
142 :
143 : namespace mozilla {
144 : namespace dom {
145 :
146 : bool Exception::sEverMadeOneFromFactory = false;
147 :
148 3 : NS_IMPL_CLASSINFO(Exception, nullptr, nsIClassInfo::DOM_OBJECT,
149 : NS_XPCEXCEPTION_CID)
150 19842 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Exception)
151 1995 : NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
152 16 : NS_INTERFACE_MAP_ENTRY(Exception)
153 16 : NS_INTERFACE_MAP_ENTRY(nsIException)
154 4 : NS_INTERFACE_MAP_ENTRY(nsIXPCException)
155 0 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIException)
156 0 : NS_IMPL_QUERY_CLASSINFO(Exception)
157 0 : NS_INTERFACE_MAP_END
158 :
159 3988 : NS_IMPL_CYCLE_COLLECTING_ADDREF(Exception)
160 2014 : NS_IMPL_CYCLE_COLLECTING_RELEASE(Exception)
161 :
162 : NS_IMPL_CYCLE_COLLECTION_CLASS(Exception)
163 :
164 1979 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Exception)
165 1979 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocation)
166 1979 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mData)
167 1979 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
168 :
169 3963 : NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(Exception)
170 3963 : NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
171 3963 : NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mThrownJSVal)
172 3963 : NS_IMPL_CYCLE_COLLECTION_TRACE_END
173 :
174 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Exception)
175 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocation)
176 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK(mData)
177 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
178 0 : tmp->mThrownJSVal.setNull();
179 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
180 :
181 0 : NS_IMPL_CI_INTERFACE_GETTER(Exception, nsIXPCException)
182 :
183 1983 : Exception::Exception(const nsACString& aMessage,
184 : nsresult aResult,
185 : const nsACString& aName,
186 : nsIStackFrame *aLocation,
187 1983 : nsISupports *aData)
188 : : mResult(NS_OK),
189 : mInitialized(false),
190 1983 : mHoldingJSVal(false)
191 : {
192 : // A little hack... The nsIGenericModule nsIClassInfo scheme relies on there
193 : // having been at least one instance made via the factory. Otherwise, the
194 : // shared factory/classinsance object never gets created and our QI getter
195 : // for our instance's pointer to our nsIClassInfo will always return null.
196 : // This is bad because it means that wrapped exceptions will never have a
197 : // shared prototype. So... We force one to be created via the factory
198 : // *once* and then go about our business.
199 1983 : if (!sEverMadeOneFromFactory) {
200 : nsCOMPtr<nsIXPCException> e =
201 4 : do_CreateInstance(XPC_EXCEPTION_CONTRACTID);
202 2 : sEverMadeOneFromFactory = true;
203 : }
204 :
205 1983 : Initialize(aMessage, aResult, aName, aLocation, aData);
206 1983 : }
207 :
208 2 : Exception::Exception()
209 : : mResult(NS_OK),
210 : mInitialized(false),
211 2 : mHoldingJSVal(false)
212 : {
213 2 : }
214 :
215 15 : Exception::~Exception()
216 : {
217 5 : if (mHoldingJSVal) {
218 0 : MOZ_ASSERT(NS_IsMainThread());
219 :
220 0 : mozilla::DropJSObjects(this);
221 : }
222 15 : }
223 :
224 : bool
225 0 : Exception::StealJSVal(JS::Value* aVp)
226 : {
227 0 : MOZ_ASSERT(NS_IsMainThread());
228 :
229 0 : if (mHoldingJSVal) {
230 0 : *aVp = mThrownJSVal;
231 0 : mThrownJSVal.setNull();
232 :
233 0 : mozilla::DropJSObjects(this);
234 0 : mHoldingJSVal = false;
235 0 : return true;
236 : }
237 :
238 0 : return false;
239 : }
240 :
241 : void
242 0 : Exception::StowJSVal(JS::Value& aVp)
243 : {
244 0 : MOZ_ASSERT(NS_IsMainThread());
245 :
246 0 : mThrownJSVal = aVp;
247 0 : if (!mHoldingJSVal) {
248 0 : mozilla::HoldJSObjects(this);
249 0 : mHoldingJSVal = true;
250 : }
251 0 : }
252 :
253 : NS_IMETHODIMP
254 0 : Exception::GetMessageMoz(nsACString& aMessage)
255 : {
256 0 : NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
257 :
258 0 : aMessage.Assign(mMessage);
259 0 : return NS_OK;
260 : }
261 :
262 : NS_IMETHODIMP
263 5 : Exception::GetResult(nsresult* aResult)
264 : {
265 5 : NS_ENSURE_ARG_POINTER(aResult);
266 5 : NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
267 :
268 5 : *aResult = mResult;
269 5 : return NS_OK;
270 : }
271 :
272 : NS_IMETHODIMP
273 0 : Exception::GetName(nsACString& aName)
274 : {
275 0 : NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
276 :
277 0 : if (!mName.IsEmpty()) {
278 0 : aName.Assign(mName);
279 : } else {
280 0 : aName.Truncate();
281 :
282 0 : const char* name = nullptr;
283 0 : nsXPCException::NameAndFormatForNSResult(mResult, &name, nullptr);
284 :
285 0 : if (name) {
286 0 : aName.Assign(name);
287 : }
288 : }
289 :
290 0 : return NS_OK;
291 : }
292 :
293 : NS_IMETHODIMP
294 0 : Exception::GetFilename(JSContext* aCx, nsAString& aFilename)
295 : {
296 0 : NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
297 :
298 0 : if (mLocation) {
299 0 : return mLocation->GetFilename(aCx, aFilename);
300 : }
301 :
302 0 : aFilename.Truncate();
303 0 : return NS_OK;
304 : }
305 :
306 : NS_IMETHODIMP
307 0 : Exception::GetLineNumber(JSContext* aCx, uint32_t *aLineNumber)
308 : {
309 0 : NS_ENSURE_ARG_POINTER(aLineNumber);
310 0 : NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
311 :
312 0 : if (mLocation) {
313 : int32_t lineno;
314 0 : nsresult rv = mLocation->GetLineNumber(aCx, &lineno);
315 0 : *aLineNumber = lineno;
316 0 : return rv;
317 : }
318 :
319 0 : *aLineNumber = 0;
320 0 : return NS_OK;
321 : }
322 :
323 : NS_IMETHODIMP
324 0 : Exception::GetColumnNumber(uint32_t* aColumnNumber)
325 : {
326 0 : NS_ENSURE_ARG_POINTER(aColumnNumber);
327 0 : NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
328 :
329 0 : *aColumnNumber = 0;
330 0 : return NS_OK;
331 : }
332 :
333 : NS_IMETHODIMP
334 0 : Exception::GetLocation(nsIStackFrame** aLocation)
335 : {
336 0 : NS_ENSURE_ARG_POINTER(aLocation);
337 0 : NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
338 :
339 0 : nsCOMPtr<nsIStackFrame> location = mLocation;
340 0 : location.forget(aLocation);
341 0 : return NS_OK;
342 : }
343 :
344 : NS_IMETHODIMP
345 0 : Exception::GetData(nsISupports** aData)
346 : {
347 0 : NS_ENSURE_ARG_POINTER(aData);
348 0 : NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
349 :
350 0 : nsCOMPtr<nsISupports> data = mData;
351 0 : data.forget(aData);
352 0 : return NS_OK;
353 : }
354 :
355 : NS_IMETHODIMP
356 0 : Exception::ToString(JSContext* aCx, nsACString& _retval)
357 : {
358 0 : NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
359 :
360 : static const char defaultMsg[] = "<no message>";
361 : static const char defaultLocation[] = "<unknown>";
362 : static const char format[] =
363 : "[Exception... \"%s\" nsresult: \"0x%" PRIx32 " (%s)\" location: \"%s\" data: %s]";
364 :
365 0 : nsCString location;
366 :
367 0 : if (mLocation) {
368 : // we need to free this if it does not fail
369 0 : nsresult rv = mLocation->ToString(aCx, location);
370 0 : NS_ENSURE_SUCCESS(rv, rv);
371 : }
372 :
373 0 : if (location.IsEmpty()) {
374 0 : location.Assign(defaultLocation);
375 : }
376 :
377 0 : const char* msg = mMessage.IsEmpty() ? nullptr : mMessage.get();
378 :
379 0 : const char* resultName = mName.IsEmpty() ? nullptr: mName.get();
380 0 : if (!resultName &&
381 0 : !nsXPCException::NameAndFormatForNSResult(mResult, &resultName,
382 0 : (!msg) ? &msg : nullptr)) {
383 0 : if (!msg) {
384 0 : msg = defaultMsg;
385 : }
386 0 : resultName = "<unknown>";
387 : }
388 0 : const char* data = mData ? "yes" : "no";
389 :
390 0 : _retval.Truncate();
391 0 : _retval.AppendPrintf(format, msg, static_cast<uint32_t>(mResult), resultName,
392 0 : location.get(), data);
393 0 : return NS_OK;
394 : }
395 :
396 : NS_IMETHODIMP
397 1983 : Exception::Initialize(const nsACString& aMessage, nsresult aResult,
398 : const nsACString& aName, nsIStackFrame *aLocation,
399 : nsISupports *aData)
400 : {
401 1983 : NS_ENSURE_FALSE(mInitialized, NS_ERROR_ALREADY_INITIALIZED);
402 :
403 1983 : mMessage = aMessage;
404 1983 : mName = aName;
405 1983 : mResult = aResult;
406 :
407 1983 : if (aLocation) {
408 0 : mLocation = aLocation;
409 : } else {
410 1983 : mLocation = GetCurrentJSStack();
411 : // it is legal for there to be no active JS stack, if C++ code
412 : // is operating on a JS-implemented interface pointer without
413 : // having been called in turn by JS. This happens in the JS
414 : // component loader.
415 : }
416 :
417 1983 : mData = aData;
418 :
419 1983 : mInitialized = true;
420 1983 : return NS_OK;
421 : }
422 :
423 : JSObject*
424 1979 : Exception::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
425 : {
426 1979 : return ExceptionBinding::Wrap(cx, this, aGivenProto);
427 : }
428 :
429 : void
430 0 : Exception::GetMessageMoz(nsString& retval)
431 : {
432 0 : nsCString str;
433 : #ifdef DEBUG
434 : DebugOnly<nsresult> rv =
435 : #endif
436 0 : GetMessageMoz(str);
437 0 : MOZ_ASSERT(NS_SUCCEEDED(rv));
438 0 : CopyUTF8toUTF16(str, retval);
439 0 : }
440 :
441 : uint32_t
442 2 : Exception::Result() const
443 : {
444 2 : return (uint32_t)mResult;
445 : }
446 :
447 : void
448 0 : Exception::GetName(nsString& retval)
449 : {
450 0 : nsCString str;
451 : #ifdef DEBUG
452 : DebugOnly<nsresult> rv =
453 : #endif
454 0 : GetName(str);
455 0 : MOZ_ASSERT(NS_SUCCEEDED(rv));
456 0 : CopyUTF8toUTF16(str, retval);
457 0 : }
458 :
459 : uint32_t
460 0 : Exception::LineNumber(JSContext* aCx) const
461 : {
462 0 : if (mLocation) {
463 : int32_t lineno;
464 0 : if (NS_SUCCEEDED(mLocation->GetLineNumber(aCx, &lineno))) {
465 0 : return lineno;
466 : }
467 0 : return 0;
468 : }
469 :
470 0 : return 0;
471 : }
472 :
473 : uint32_t
474 0 : Exception::ColumnNumber() const
475 : {
476 0 : return 0;
477 : }
478 :
479 : already_AddRefed<nsIStackFrame>
480 0 : Exception::GetLocation() const
481 : {
482 0 : nsCOMPtr<nsIStackFrame> location = mLocation;
483 0 : return location.forget();
484 : }
485 :
486 : already_AddRefed<nsISupports>
487 0 : Exception::GetData() const
488 : {
489 0 : nsCOMPtr<nsISupports> data = mData;
490 0 : return data.forget();
491 : }
492 :
493 : void
494 0 : Exception::GetStack(JSContext* aCx, nsAString& aStack, ErrorResult& aRv) const
495 : {
496 0 : if (mLocation) {
497 0 : aRv = mLocation->GetFormattedStack(aCx, aStack);
498 : }
499 0 : }
500 :
501 : void
502 0 : Exception::Stringify(JSContext* aCx, nsString& retval)
503 : {
504 0 : nsCString str;
505 : #ifdef DEBUG
506 : DebugOnly<nsresult> rv =
507 : #endif
508 0 : ToString(aCx, str);
509 0 : MOZ_ASSERT(NS_SUCCEEDED(rv));
510 0 : CopyUTF8toUTF16(str, retval);
511 0 : }
512 :
513 0 : NS_IMPL_ADDREF_INHERITED(DOMException, Exception)
514 0 : NS_IMPL_RELEASE_INHERITED(DOMException, Exception)
515 0 : NS_INTERFACE_MAP_BEGIN(DOMException)
516 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMDOMException)
517 0 : NS_INTERFACE_MAP_END_INHERITING(Exception)
518 :
519 0 : DOMException::DOMException(nsresult aRv, const nsACString& aMessage,
520 0 : const nsACString& aName, uint16_t aCode)
521 0 : : Exception(EmptyCString(), aRv, EmptyCString(), nullptr, nullptr),
522 : mName(aName),
523 : mMessage(aMessage),
524 0 : mCode(aCode)
525 : {
526 0 : }
527 :
528 : NS_IMETHODIMP
529 0 : DOMException::GetCode(uint16_t* aCode)
530 : {
531 0 : NS_ENSURE_ARG_POINTER(aCode);
532 0 : *aCode = mCode;
533 :
534 : // Warn only when the code was changed (other than DOM Core)
535 : // or the code is useless (zero)
536 0 : if (NS_ERROR_GET_MODULE(mResult) != NS_ERROR_MODULE_DOM || !mCode) {
537 0 : nsCOMPtr<nsIDocument> doc = nsContentUtils::GetDocumentFromCaller();
538 0 : if (doc) {
539 0 : doc->WarnOnceAbout(nsIDocument::eDOMExceptionCode);
540 : }
541 : }
542 :
543 0 : return NS_OK;
544 : }
545 :
546 : NS_IMETHODIMP
547 0 : DOMException::ToString(JSContext* aCx, nsACString& aReturn)
548 : {
549 0 : aReturn.Truncate();
550 :
551 : static const char defaultMsg[] = "<no message>";
552 : static const char defaultLocation[] = "<unknown>";
553 : static const char defaultName[] = "<unknown>";
554 : static const char format[] =
555 : "[Exception... \"%s\" code: \"%d\" nsresult: \"0x%" PRIx32 " (%s)\" location: \"%s\"]";
556 :
557 0 : nsAutoCString location;
558 :
559 0 : if (location.IsEmpty()) {
560 0 : location = defaultLocation;
561 : }
562 :
563 0 : const char* msg = !mMessage.IsEmpty() ? mMessage.get() : defaultMsg;
564 0 : const char* resultName = !mName.IsEmpty() ? mName.get() : defaultName;
565 :
566 0 : aReturn.AppendPrintf(format, msg, mCode, static_cast<uint32_t>(mResult), resultName,
567 0 : location.get());
568 :
569 0 : return NS_OK;
570 : }
571 :
572 : void
573 0 : DOMException::GetName(nsString& retval)
574 : {
575 0 : CopyUTF8toUTF16(mName, retval);
576 0 : }
577 :
578 : void
579 0 : DOMException::GetMessageMoz(nsString& retval)
580 : {
581 0 : CopyUTF8toUTF16(mMessage, retval);
582 0 : }
583 :
584 : already_AddRefed<DOMException>
585 0 : DOMException::Constructor(GlobalObject& /* unused */,
586 : const nsAString& aMessage,
587 : const Optional<nsAString>& aName,
588 : ErrorResult& aError)
589 : {
590 0 : nsresult exceptionResult = NS_OK;
591 0 : uint16_t exceptionCode = 0;
592 0 : nsCString name(NS_LITERAL_CSTRING("Error"));
593 :
594 0 : if (aName.WasPassed()) {
595 0 : CopyUTF16toUTF8(aName.Value(), name);
596 0 : for (uint32_t idx = 0; idx < ArrayLength(sDOMErrorMsgMap); idx++) {
597 0 : if (name.EqualsASCII(sDOMErrorMsgMap[idx].mName)) {
598 0 : exceptionResult = sDOMErrorMsgMap[idx].mNSResult;
599 0 : exceptionCode = sDOMErrorMsgMap[idx].mCode;
600 0 : break;
601 : }
602 : }
603 : }
604 :
605 : RefPtr<DOMException> retval =
606 : new DOMException(exceptionResult,
607 0 : NS_ConvertUTF16toUTF8(aMessage),
608 : name,
609 0 : exceptionCode);
610 0 : return retval.forget();
611 : }
612 :
613 : JSObject*
614 0 : DOMException::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
615 : {
616 0 : return DOMExceptionBinding::Wrap(aCx, this, aGivenProto);
617 : }
618 :
619 : /* static */already_AddRefed<DOMException>
620 0 : DOMException::Create(nsresult aRv)
621 : {
622 0 : nsCString name;
623 0 : nsCString message;
624 : uint16_t code;
625 0 : NSResultToNameAndMessage(aRv, name, message, &code);
626 : RefPtr<DOMException> inst =
627 0 : new DOMException(aRv, message, name, code);
628 0 : return inst.forget();
629 : }
630 :
631 : /* static */already_AddRefed<DOMException>
632 0 : DOMException::Create(nsresult aRv, const nsACString& aMessage)
633 : {
634 0 : nsCString name;
635 0 : nsCString message;
636 : uint16_t code;
637 0 : NSResultToNameAndMessage(aRv, name, message, &code);
638 : RefPtr<DOMException> inst =
639 0 : new DOMException(aRv, aMessage, name, code);
640 0 : return inst.forget();
641 : }
642 :
643 : } // namespace dom
644 : } // namespace mozilla
|