dom/base/DOMException.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial