dom/base/DOMException.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/dom/base/DOMException.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,675 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#include "mozilla/dom/DOMException.h"
    1.10 +
    1.11 +#include "jsprf.h"
    1.12 +#include "js/OldDebugAPI.h"
    1.13 +#include "mozilla/ArrayUtils.h"
    1.14 +#include "mozilla/HoldDropJSObjects.h"
    1.15 +#include "mozilla/dom/Exceptions.h"
    1.16 +#include "nsContentUtils.h"
    1.17 +#include "nsCOMPtr.h"
    1.18 +#include "nsIClassInfoImpl.h"
    1.19 +#include "nsIDocument.h"
    1.20 +#include "nsIDOMDOMException.h"
    1.21 +#include "nsIException.h"
    1.22 +#include "nsIProgrammingLanguage.h"
    1.23 +#include "nsMemory.h"
    1.24 +#include "prprf.h"
    1.25 +#include "xpcprivate.h"
    1.26 +
    1.27 +#include "mozilla/dom/DOMExceptionBinding.h"
    1.28 +
    1.29 +using namespace mozilla;
    1.30 +
    1.31 +enum DOM4ErrorTypeCodeMap {
    1.32 +  /* DOM4 errors from http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#domexception */
    1.33 +  IndexSizeError             = nsIDOMDOMException::INDEX_SIZE_ERR,
    1.34 +  HierarchyRequestError      = nsIDOMDOMException::HIERARCHY_REQUEST_ERR,
    1.35 +  WrongDocumentError         = nsIDOMDOMException::WRONG_DOCUMENT_ERR,
    1.36 +  InvalidCharacterError      = nsIDOMDOMException::INVALID_CHARACTER_ERR,
    1.37 +  NoModificationAllowedError = nsIDOMDOMException::NO_MODIFICATION_ALLOWED_ERR,
    1.38 +  NotFoundError              = nsIDOMDOMException::NOT_FOUND_ERR,
    1.39 +  NotSupportedError          = nsIDOMDOMException::NOT_SUPPORTED_ERR,
    1.40 +  // Can't remove until setNamedItem is removed
    1.41 +  InUseAttributeError        = nsIDOMDOMException::INUSE_ATTRIBUTE_ERR,
    1.42 +  InvalidStateError          = nsIDOMDOMException::INVALID_STATE_ERR,
    1.43 +  SyntaxError                = nsIDOMDOMException::SYNTAX_ERR,
    1.44 +  InvalidModificationError   = nsIDOMDOMException::INVALID_MODIFICATION_ERR,
    1.45 +  NamespaceError             = nsIDOMDOMException::NAMESPACE_ERR,
    1.46 +  InvalidAccessError         = nsIDOMDOMException::INVALID_ACCESS_ERR,
    1.47 +  TypeMismatchError          = nsIDOMDOMException::TYPE_MISMATCH_ERR,
    1.48 +  SecurityError              = nsIDOMDOMException::SECURITY_ERR,
    1.49 +  NetworkError               = nsIDOMDOMException::NETWORK_ERR,
    1.50 +  AbortError                 = nsIDOMDOMException::ABORT_ERR,
    1.51 +  URLMismatchError           = nsIDOMDOMException::URL_MISMATCH_ERR,
    1.52 +  QuotaExceededError         = nsIDOMDOMException::QUOTA_EXCEEDED_ERR,
    1.53 +  TimeoutError               = nsIDOMDOMException::TIMEOUT_ERR,
    1.54 +  InvalidNodeTypeError       = nsIDOMDOMException::INVALID_NODE_TYPE_ERR,
    1.55 +  DataCloneError             = nsIDOMDOMException::DATA_CLONE_ERR,
    1.56 +  InvalidPointerId           = nsIDOMDOMException::INVALID_POINTER_ERR,
    1.57 +  EncodingError              = 0,
    1.58 +
    1.59 +  /* XXX Should be JavaScript native errors */
    1.60 +  TypeError                  = 0,
    1.61 +  RangeError                 = 0,
    1.62 +
    1.63 +  /* IndexedDB errors http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#exceptions */
    1.64 +  UnknownError             = 0,
    1.65 +  ConstraintError          = 0,
    1.66 +  DataError                = 0,
    1.67 +  TransactionInactiveError = 0,
    1.68 +  ReadOnlyError            = 0,
    1.69 +  VersionError             = 0,
    1.70 +
    1.71 +  /* File API errors http://dev.w3.org/2006/webapi/FileAPI/#ErrorAndException */
    1.72 +  NotReadableError         = 0,
    1.73 +
    1.74 +  /* FileHandle API errors */
    1.75 +  LockedFileInactiveError = 0,
    1.76 +};
    1.77 +
    1.78 +#define DOM4_MSG_DEF(name, message, nsresult) {(nsresult), name, #name, message},
    1.79 +#define DOM_MSG_DEF(val, message) {(val), NS_ERROR_GET_CODE(val), #val, message},
    1.80 +
    1.81 +static const struct ResultStruct
    1.82 +{
    1.83 +  nsresult mNSResult;
    1.84 +  uint16_t mCode;
    1.85 +  const char* mName;
    1.86 +  const char* mMessage;
    1.87 +} sDOMErrorMsgMap[] = {
    1.88 +#include "domerr.msg"
    1.89 +};
    1.90 +
    1.91 +#undef DOM4_MSG_DEF
    1.92 +#undef DOM_MSG_DEF
    1.93 +
    1.94 +static void
    1.95 +NSResultToNameAndMessage(nsresult aNSResult,
    1.96 +                         nsCString& aName,
    1.97 +                         nsCString& aMessage,
    1.98 +                         uint16_t* aCode)
    1.99 +{
   1.100 +  aName.Truncate();
   1.101 +  aMessage.Truncate();
   1.102 +  *aCode = 0;
   1.103 +  for (uint32_t idx = 0; idx < ArrayLength(sDOMErrorMsgMap); idx++) {
   1.104 +    if (aNSResult == sDOMErrorMsgMap[idx].mNSResult) {
   1.105 +      aName.Rebind(sDOMErrorMsgMap[idx].mName,
   1.106 +                   strlen(sDOMErrorMsgMap[idx].mName));
   1.107 +      aMessage.Rebind(sDOMErrorMsgMap[idx].mMessage,
   1.108 +                   strlen(sDOMErrorMsgMap[idx].mMessage));
   1.109 +      *aCode = sDOMErrorMsgMap[idx].mCode;
   1.110 +      return;
   1.111 +    }
   1.112 +  }
   1.113 +
   1.114 +  NS_WARNING("Huh, someone is throwing non-DOM errors using the DOM module!");
   1.115 +
   1.116 +  return;
   1.117 +}
   1.118 +
   1.119 +nsresult
   1.120 +NS_GetNameAndMessageForDOMNSResult(nsresult aNSResult, nsACString& aName,
   1.121 +                                   nsACString& aMessage, uint16_t* aCode)
   1.122 +{
   1.123 +  nsCString name;
   1.124 +  nsCString message;
   1.125 +  uint16_t code = 0;
   1.126 +  NSResultToNameAndMessage(aNSResult, name, message, &code);
   1.127 +
   1.128 +  if (!name.IsEmpty() && !message.IsEmpty()) {
   1.129 +    aName = name;
   1.130 +    aMessage = message;
   1.131 +    if (aCode) {
   1.132 +      *aCode = code;
   1.133 +    }
   1.134 +    return NS_OK;
   1.135 +  }
   1.136 +
   1.137 +  return NS_ERROR_NOT_AVAILABLE;
   1.138 +}
   1.139 +
   1.140 +namespace mozilla {
   1.141 +namespace dom {
   1.142 +
   1.143 +bool Exception::sEverMadeOneFromFactory = false;
   1.144 +
   1.145 +NS_IMPL_CLASSINFO(Exception, nullptr, nsIClassInfo::DOM_OBJECT,
   1.146 +                  NS_XPCEXCEPTION_CID)
   1.147 +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Exception)
   1.148 +  NS_INTERFACE_MAP_ENTRY(nsIException)
   1.149 +  NS_INTERFACE_MAP_ENTRY(nsIXPCException)
   1.150 +  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIException)
   1.151 +  NS_IMPL_QUERY_CLASSINFO(Exception)
   1.152 +NS_INTERFACE_MAP_END
   1.153 +
   1.154 +NS_IMPL_CYCLE_COLLECTING_ADDREF(Exception)
   1.155 +NS_IMPL_CYCLE_COLLECTING_RELEASE(Exception)
   1.156 +
   1.157 +NS_IMPL_CYCLE_COLLECTION_CLASS(Exception)
   1.158 +
   1.159 +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Exception)
   1.160 +  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocation)
   1.161 +  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mInner)
   1.162 +  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
   1.163 +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
   1.164 +
   1.165 +NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(Exception)
   1.166 +  NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
   1.167 +  NS_IMPL_CYCLE_COLLECTION_TRACE_JSVAL_MEMBER_CALLBACK(mThrownJSVal);
   1.168 +NS_IMPL_CYCLE_COLLECTION_TRACE_END
   1.169 +
   1.170 +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Exception)
   1.171 +  NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocation)
   1.172 +  NS_IMPL_CYCLE_COLLECTION_UNLINK(mInner)
   1.173 +  NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
   1.174 +  tmp->mThrownJSVal.setNull();
   1.175 +NS_IMPL_CYCLE_COLLECTION_UNLINK_END
   1.176 +
   1.177 +NS_IMPL_CI_INTERFACE_GETTER(Exception, nsIXPCException)
   1.178 +
   1.179 +Exception::Exception(const nsACString& aMessage,
   1.180 +                     nsresult aResult,
   1.181 +                     const nsACString& aName,
   1.182 +                     nsIStackFrame *aLocation,
   1.183 +                     nsISupports *aData)
   1.184 +: mResult(NS_OK),
   1.185 +  mLineNumber(0),
   1.186 +  mInitialized(false),
   1.187 +  mHoldingJSVal(false)
   1.188 +{
   1.189 +  SetIsDOMBinding();
   1.190 +
   1.191 +  // A little hack... The nsIGenericModule nsIClassInfo scheme relies on there
   1.192 +  // having been at least one instance made via the factory. Otherwise, the
   1.193 +  // shared factory/classinsance object never gets created and our QI getter
   1.194 +  // for our instance's pointer to our nsIClassInfo will always return null.
   1.195 +  // This is bad because it means that wrapped exceptions will never have a
   1.196 +  // shared prototype. So... We force one to be created via the factory
   1.197 +  // *once* and then go about our business.
   1.198 +  if (!sEverMadeOneFromFactory) {
   1.199 +    nsCOMPtr<nsIXPCException> e =
   1.200 +        do_CreateInstance(XPC_EXCEPTION_CONTRACTID);
   1.201 +    sEverMadeOneFromFactory = true;
   1.202 +  }
   1.203 +
   1.204 +  nsCOMPtr<nsIStackFrame> location;
   1.205 +  if (aLocation) {
   1.206 +    location = aLocation;
   1.207 +  } else {
   1.208 +    location = GetCurrentJSStack();
   1.209 +    // it is legal for there to be no active JS stack, if C++ code
   1.210 +    // is operating on a JS-implemented interface pointer without
   1.211 +    // having been called in turn by JS.  This happens in the JS
   1.212 +    // component loader, and will become more common as additional
   1.213 +    // components are implemented in JS.
   1.214 +  }
   1.215 +  // We want to trim off any leading native 'dataless' frames
   1.216 +  if (location) {
   1.217 +    while (1) {
   1.218 +      uint32_t language;
   1.219 +      int32_t lineNumber;
   1.220 +      if (NS_FAILED(location->GetLanguage(&language)) ||
   1.221 +          language == nsIProgrammingLanguage::JAVASCRIPT ||
   1.222 +          NS_FAILED(location->GetLineNumber(&lineNumber)) ||
   1.223 +          lineNumber) {
   1.224 +        break;
   1.225 +      }
   1.226 +      nsCOMPtr<nsIStackFrame> caller;
   1.227 +      if (NS_FAILED(location->GetCaller(getter_AddRefs(caller))) || !caller) {
   1.228 +        break;
   1.229 +      }
   1.230 +      location = caller;
   1.231 +    }
   1.232 +  }
   1.233 +
   1.234 +  Initialize(aMessage, aResult, aName, location, aData, nullptr);
   1.235 +}
   1.236 +
   1.237 +Exception::Exception()
   1.238 +  : mResult(NS_OK),
   1.239 +    mLineNumber(-1),
   1.240 +    mInitialized(false),
   1.241 +    mHoldingJSVal(false)
   1.242 +{
   1.243 +}
   1.244 +
   1.245 +Exception::~Exception()
   1.246 +{
   1.247 +  if (mHoldingJSVal) {
   1.248 +    MOZ_ASSERT(NS_IsMainThread());
   1.249 +
   1.250 +    mozilla::DropJSObjects(this);
   1.251 +  }
   1.252 +}
   1.253 +
   1.254 +bool
   1.255 +Exception::StealJSVal(JS::Value* aVp)
   1.256 +{
   1.257 +  MOZ_ASSERT(NS_IsMainThread());
   1.258 +
   1.259 +  if (mHoldingJSVal) {
   1.260 +    *aVp = mThrownJSVal;
   1.261 +    mThrownJSVal.setNull();
   1.262 +
   1.263 +    mozilla::DropJSObjects(this);
   1.264 +    mHoldingJSVal = false;
   1.265 +    return true;
   1.266 +  }
   1.267 +
   1.268 +  return false;
   1.269 +}
   1.270 +
   1.271 +void
   1.272 +Exception::StowJSVal(JS::Value& aVp)
   1.273 +{
   1.274 +  MOZ_ASSERT(NS_IsMainThread());
   1.275 +
   1.276 +  mThrownJSVal = aVp;
   1.277 +  if (!mHoldingJSVal) {
   1.278 +    mozilla::HoldJSObjects(this);
   1.279 +    mHoldingJSVal = true;
   1.280 +  }
   1.281 +}
   1.282 +
   1.283 +/* readonly attribute AUTF8String message; */
   1.284 +NS_IMETHODIMP
   1.285 +Exception::GetMessageMoz(nsACString& aMessage)
   1.286 +{
   1.287 +  NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
   1.288 +
   1.289 +  aMessage.Assign(mMessage);
   1.290 +  return NS_OK;
   1.291 +}
   1.292 +
   1.293 +/* readonly attribute nsresult result; */
   1.294 +NS_IMETHODIMP
   1.295 +Exception::GetResult(nsresult* aResult)
   1.296 +{
   1.297 +  NS_ENSURE_ARG_POINTER(aResult);
   1.298 +  NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
   1.299 +
   1.300 +  *aResult = mResult;
   1.301 +  return NS_OK;
   1.302 +}
   1.303 +
   1.304 +/* readonly attribute AUTF8String name; */
   1.305 +NS_IMETHODIMP
   1.306 +Exception::GetName(nsACString& aName)
   1.307 +{
   1.308 +  NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
   1.309 +
   1.310 +  if (!mName.IsEmpty()) {
   1.311 +    aName.Assign(mName);
   1.312 +  } else {
   1.313 +    aName.Truncate();
   1.314 +
   1.315 +    const char* name = nullptr;
   1.316 +    nsXPCException::NameAndFormatForNSResult(mResult, &name, nullptr);
   1.317 +
   1.318 +    if (name) {
   1.319 +      aName.Assign(name);
   1.320 +    }
   1.321 +  }
   1.322 +
   1.323 +  return NS_OK;
   1.324 +}
   1.325 +
   1.326 +/* readonly attribute AString filename; */
   1.327 +NS_IMETHODIMP
   1.328 +Exception::GetFilename(nsAString& aFilename)
   1.329 +{
   1.330 +  NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
   1.331 +
   1.332 +  if (mLocation) {
   1.333 +    return mLocation->GetFilename(aFilename);
   1.334 +  }
   1.335 +
   1.336 +  aFilename.Assign(mFilename);
   1.337 +  return NS_OK;
   1.338 +}
   1.339 +
   1.340 +/* readonly attribute uint32_t lineNumber; */
   1.341 +NS_IMETHODIMP
   1.342 +Exception::GetLineNumber(uint32_t *aLineNumber)
   1.343 +{
   1.344 +  NS_ENSURE_ARG_POINTER(aLineNumber);
   1.345 +  NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
   1.346 +
   1.347 +  if (mLocation) {
   1.348 +    int32_t lineno;
   1.349 +    nsresult rv = mLocation->GetLineNumber(&lineno);
   1.350 +    *aLineNumber = lineno;
   1.351 +    return rv;
   1.352 +  }
   1.353 +
   1.354 +  *aLineNumber = mLineNumber;
   1.355 +  return NS_OK;
   1.356 +}
   1.357 +
   1.358 +/* readonly attribute uint32_t columnNumber; */
   1.359 +NS_IMETHODIMP
   1.360 +Exception::GetColumnNumber(uint32_t* aColumnNumber)
   1.361 +{
   1.362 +  NS_ENSURE_ARG_POINTER(aColumnNumber);
   1.363 +  NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
   1.364 +
   1.365 +  *aColumnNumber = 0;
   1.366 +  return NS_OK;
   1.367 +}
   1.368 +
   1.369 +/* readonly attribute nsIStackFrame location; */
   1.370 +NS_IMETHODIMP
   1.371 +Exception::GetLocation(nsIStackFrame** aLocation)
   1.372 +{
   1.373 +  NS_ENSURE_ARG_POINTER(aLocation);
   1.374 +  NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
   1.375 +
   1.376 +  nsCOMPtr<nsIStackFrame> location = mLocation;
   1.377 +  location.forget(aLocation);
   1.378 +  return NS_OK;
   1.379 +}
   1.380 +
   1.381 +/* readonly attribute nsISupports data; */
   1.382 +NS_IMETHODIMP
   1.383 +Exception::GetData(nsISupports** aData)
   1.384 +{
   1.385 +  NS_ENSURE_ARG_POINTER(aData);
   1.386 +  NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
   1.387 +
   1.388 +  nsCOMPtr<nsISupports> data = mData;
   1.389 +  data.forget(aData);
   1.390 +  return NS_OK;
   1.391 +}
   1.392 +
   1.393 +/* readonly attribute nsIException inner; */
   1.394 +NS_IMETHODIMP
   1.395 +Exception::GetInner(nsIException** aException)
   1.396 +{
   1.397 +  NS_ENSURE_ARG_POINTER(aException);
   1.398 +  NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
   1.399 +
   1.400 +  nsCOMPtr<nsIException> inner = mInner;
   1.401 +  inner.forget(aException);
   1.402 +  return NS_OK;
   1.403 +}
   1.404 +
   1.405 +/* AUTF8String toString (); */
   1.406 +NS_IMETHODIMP
   1.407 +Exception::ToString(nsACString& _retval)
   1.408 +{
   1.409 +  NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
   1.410 +
   1.411 +  static const char defaultMsg[] = "<no message>";
   1.412 +  static const char defaultLocation[] = "<unknown>";
   1.413 +  static const char format[] =
   1.414 +"[Exception... \"%s\"  nsresult: \"0x%x (%s)\"  location: \"%s\"  data: %s]";
   1.415 +
   1.416 +  nsCString location;
   1.417 +
   1.418 +  if (mLocation) {
   1.419 +    // we need to free this if it does not fail
   1.420 +    nsresult rv = mLocation->ToString(location);
   1.421 +    NS_ENSURE_SUCCESS(rv, rv);
   1.422 +  }
   1.423 +
   1.424 +  if (location.IsEmpty()) {
   1.425 +    location.Assign(defaultLocation);
   1.426 +  }
   1.427 +
   1.428 +  const char* msg = mMessage.IsEmpty() ? nullptr : mMessage.get();
   1.429 +
   1.430 +  const char* resultName = mName.IsEmpty() ? nullptr: mName.get();
   1.431 +  if (!resultName &&
   1.432 +      !nsXPCException::NameAndFormatForNSResult(mResult, &resultName,
   1.433 +                                                (!msg) ? &msg : nullptr)) {
   1.434 +    if (!msg) {
   1.435 +      msg = defaultMsg;
   1.436 +    }
   1.437 +    resultName = "<unknown>";
   1.438 +  }
   1.439 +  const char* data = mData ? "yes" : "no";
   1.440 +
   1.441 +  _retval.Truncate();
   1.442 +  _retval.AppendPrintf(format, msg, mResult, resultName,
   1.443 +                       location.get(), data);
   1.444 +  return NS_OK;
   1.445 +}
   1.446 +
   1.447 +/* void initialize (in AUTF8String aMessage, in nsresult aResult,
   1.448 + *                  in AUTF8String aName, in nsIStackFrame aLocation,
   1.449 + *                  in nsISupports aData, in nsIException aInner); */
   1.450 +NS_IMETHODIMP
   1.451 +Exception::Initialize(const nsACString& aMessage, nsresult aResult,
   1.452 +                      const nsACString& aName, nsIStackFrame *aLocation,
   1.453 +                      nsISupports *aData, nsIException *aInner)
   1.454 +{
   1.455 +  NS_ENSURE_FALSE(mInitialized, NS_ERROR_ALREADY_INITIALIZED);
   1.456 +
   1.457 +  mMessage = aMessage;
   1.458 +  mName = aName;
   1.459 +  mResult = aResult;
   1.460 +
   1.461 +  if (aLocation) {
   1.462 +    mLocation = aLocation;
   1.463 +  } else {
   1.464 +    nsresult rv;
   1.465 +    nsXPConnect* xpc = nsXPConnect::XPConnect();
   1.466 +    rv = xpc->GetCurrentJSStack(getter_AddRefs(mLocation));
   1.467 +    if (NS_FAILED(rv)) {
   1.468 +      return rv;
   1.469 +    }
   1.470 +  }
   1.471 +
   1.472 +  mData = aData;
   1.473 +  mInner = aInner;
   1.474 +
   1.475 +  mInitialized = true;
   1.476 +  return NS_OK;
   1.477 +}
   1.478 +
   1.479 +JSObject*
   1.480 +Exception::WrapObject(JSContext* cx)
   1.481 +{
   1.482 +  return ExceptionBinding::Wrap(cx, this);
   1.483 +}
   1.484 +
   1.485 +void
   1.486 +Exception::GetMessageMoz(nsString& retval)
   1.487 +{
   1.488 +  nsCString str;
   1.489 +#ifdef DEBUG
   1.490 +  DebugOnly<nsresult> rv = 
   1.491 +#endif
   1.492 +  GetMessageMoz(str);
   1.493 +  MOZ_ASSERT(NS_SUCCEEDED(rv));
   1.494 +  CopyUTF8toUTF16(str, retval);
   1.495 +}
   1.496 +
   1.497 +uint32_t
   1.498 +Exception::Result() const
   1.499 +{
   1.500 +  return (uint32_t)mResult;
   1.501 +}
   1.502 +
   1.503 +void
   1.504 +Exception::GetName(nsString& retval)
   1.505 +{
   1.506 +  nsCString str;
   1.507 +#ifdef DEBUG
   1.508 +  DebugOnly<nsresult> rv =
   1.509 +#endif
   1.510 +  GetName(str);
   1.511 +  MOZ_ASSERT(NS_SUCCEEDED(rv));
   1.512 +  CopyUTF8toUTF16(str, retval);
   1.513 +}
   1.514 +
   1.515 +uint32_t
   1.516 +Exception::LineNumber() const
   1.517 +{
   1.518 +  if (mLocation) {
   1.519 +    int32_t lineno;
   1.520 +    if (NS_SUCCEEDED(mLocation->GetLineNumber(&lineno))) {
   1.521 +      return lineno;
   1.522 +    }
   1.523 +    return 0;
   1.524 +  }
   1.525 +
   1.526 +  return mLineNumber;
   1.527 +}
   1.528 +
   1.529 +uint32_t
   1.530 +Exception::ColumnNumber() const
   1.531 +{
   1.532 +  return 0;
   1.533 +}
   1.534 +
   1.535 +already_AddRefed<nsIStackFrame>
   1.536 +Exception::GetLocation() const
   1.537 +{
   1.538 +  nsCOMPtr<nsIStackFrame> location = mLocation;
   1.539 +  return location.forget();
   1.540 +}
   1.541 +
   1.542 +already_AddRefed<nsISupports>
   1.543 +Exception::GetInner() const
   1.544 +{
   1.545 +  nsCOMPtr<nsIException> inner = mInner;
   1.546 +  return inner.forget();
   1.547 +}
   1.548 +
   1.549 +already_AddRefed<nsISupports>
   1.550 +Exception::GetData() const
   1.551 +{
   1.552 +  nsCOMPtr<nsISupports> data = mData;
   1.553 +  return data.forget();
   1.554 +}
   1.555 +
   1.556 +void
   1.557 +Exception::Stringify(nsString& retval)
   1.558 +{
   1.559 +  nsCString str;
   1.560 +#ifdef DEBUG
   1.561 +  DebugOnly<nsresult> rv =
   1.562 +#endif
   1.563 +  ToString(str);
   1.564 +  MOZ_ASSERT(NS_SUCCEEDED(rv));
   1.565 +  CopyUTF8toUTF16(str, retval);
   1.566 +}
   1.567 +
   1.568 +NS_IMPL_ADDREF_INHERITED(DOMException, Exception)
   1.569 +NS_IMPL_RELEASE_INHERITED(DOMException, Exception)
   1.570 +NS_INTERFACE_MAP_BEGIN(DOMException)
   1.571 +  NS_INTERFACE_MAP_ENTRY(nsIDOMDOMException)
   1.572 +NS_INTERFACE_MAP_END_INHERITING(Exception)
   1.573 +
   1.574 +DOMException::DOMException(nsresult aRv, const nsACString& aMessage,
   1.575 +                           const nsACString& aName, uint16_t aCode)
   1.576 +  : Exception(EmptyCString(), aRv, EmptyCString(), nullptr, nullptr),
   1.577 +    mName(aName),
   1.578 +    mMessage(aMessage),
   1.579 +    mCode(aCode)
   1.580 +{
   1.581 +  SetIsDOMBinding();
   1.582 +}
   1.583 +
   1.584 +NS_IMETHODIMP
   1.585 +DOMException::GetCode(uint16_t* aCode)
   1.586 +{
   1.587 +  NS_ENSURE_ARG_POINTER(aCode);
   1.588 +  *aCode = mCode;
   1.589 +
   1.590 +  // Warn only when the code was changed (other than DOM Core)
   1.591 +  // or the code is useless (zero)
   1.592 +  if (NS_ERROR_GET_MODULE(mResult) != NS_ERROR_MODULE_DOM || !mCode) {
   1.593 +    nsCOMPtr<nsIDocument> doc = nsContentUtils::GetDocumentFromCaller();
   1.594 +    if (doc) {
   1.595 +      doc->WarnOnceAbout(nsIDocument::eDOMExceptionCode);
   1.596 +    }
   1.597 +  }
   1.598 +
   1.599 +  return NS_OK;
   1.600 +}
   1.601 +
   1.602 +NS_IMETHODIMP
   1.603 +DOMException::ToString(nsACString& aReturn)
   1.604 +{
   1.605 +  aReturn.Truncate();
   1.606 +
   1.607 +  static const char defaultMsg[] = "<no message>";
   1.608 +  static const char defaultLocation[] = "<unknown>";
   1.609 +  static const char defaultName[] = "<unknown>";
   1.610 +  static const char format[] =
   1.611 +    "[Exception... \"%s\"  code: \"%d\" nsresult: \"0x%x (%s)\"  location: \"%s\"]";
   1.612 +
   1.613 +  nsAutoCString location;
   1.614 +
   1.615 +  if (mInner) {
   1.616 +    nsString filename;
   1.617 +    mInner->GetFilename(filename);
   1.618 +
   1.619 +    if (!filename.IsEmpty()) {
   1.620 +      uint32_t line_nr = 0;
   1.621 +
   1.622 +      mInner->GetLineNumber(&line_nr);
   1.623 +
   1.624 +      char *temp = PR_smprintf("%s Line: %d",
   1.625 +                               NS_ConvertUTF16toUTF8(filename).get(),
   1.626 +                               line_nr);
   1.627 +      if (temp) {
   1.628 +        location.Assign(temp);
   1.629 +        PR_smprintf_free(temp);
   1.630 +      }
   1.631 +    }
   1.632 +  }
   1.633 +
   1.634 +  if (location.IsEmpty()) {
   1.635 +    location = defaultLocation;
   1.636 +  }
   1.637 +
   1.638 +  const char* msg = !mMessage.IsEmpty() ? mMessage.get() : defaultMsg;
   1.639 +  const char* resultName = !mName.IsEmpty() ? mName.get() : defaultName;
   1.640 +
   1.641 +  aReturn.AppendPrintf(format, msg, mCode, mResult, resultName,
   1.642 +                       location.get());
   1.643 +
   1.644 +  return NS_OK;
   1.645 +}
   1.646 +
   1.647 +void
   1.648 +DOMException::GetName(nsString& retval)
   1.649 +{
   1.650 +  CopyUTF8toUTF16(mName, retval);
   1.651 +}
   1.652 +
   1.653 +void
   1.654 +DOMException::GetMessageMoz(nsString& retval)
   1.655 +{
   1.656 +  CopyUTF8toUTF16(mMessage, retval);
   1.657 +}
   1.658 +
   1.659 +JSObject*
   1.660 +DOMException::WrapObject(JSContext* aCx)
   1.661 +{
   1.662 +  return DOMExceptionBinding::Wrap(aCx, this);
   1.663 +}
   1.664 +
   1.665 +/* static */already_AddRefed<DOMException>
   1.666 +DOMException::Create(nsresult aRv)
   1.667 +{
   1.668 +  nsCString name;
   1.669 +  nsCString message;
   1.670 +  uint16_t code;
   1.671 +  NSResultToNameAndMessage(aRv, name, message, &code);
   1.672 +  nsRefPtr<DOMException> inst =
   1.673 +    new DOMException(aRv, message, name, code);
   1.674 +  return inst.forget();
   1.675 +}
   1.676 +
   1.677 +} // namespace dom
   1.678 +} // namespace mozilla

mercurial