nsCOMPtr<nsIScriptGlobalObjectOwner> owner; if(NS_FAILED(globalObject->GetGlobalObjectOwner(getter_AddRefs(owner))) || !owner) { NS_WARNING("Failed to get a global Object Owner"); return; }
NS_ScriptErrorReporter(JSContext *cx,                       const char *message,                       JSErrorReport *report){  nsCOMPtr<nsIScriptContext> context;  nsEventStatus status = nsEventStatus_eIgnore;  // XXX this means we are not going to get error reports on non DOM contexts  nsJSUtils::GetDynamicScriptContext(cx, getter_AddRefs(context));  if (context) {    nsCOMPtr<nsIScriptGlobalObject> globalObject;    context->GetGlobalObject(getter_AddRefs(globalObject));    if (globalObject) {      nsCOMPtr<nsIScriptGlobalObjectOwner> owner;      if(NS_FAILED(globalObject->GetGlobalObjectOwner(getter_AddRefs(owner))) ||         !owner) {        NS_WARNING("Failed to get a global Object Owner");        return;      }      nsAutoString fileName, msg;      if (report) {        fileName.AssignWithConversion(report->filename);        const PRUnichar *m = NS_REINTERPRET_CAST(const PRUnichar*,                                                 report->ucmessage);        if (m) {          msg.Assign(m);        }      }      if (msg.IsEmpty() && message) {        msg.AssignWithConversion(message);      }      //send error event first, then proceed      nsCOMPtr<nsIDocShell> docShell;      globalObject->GetDocShell(getter_AddRefs(docShell));      if (docShell && !JSREPORT_IS_WARNING(report->flags)) {        static PRInt32 errorDepth; // Recursion prevention        errorDepth++;        nsCOMPtr<nsIPresContext> presContext;        docShell->GetPresContext(getter_AddRefs(presContext));        if(presContext && errorDepth < 2) {          nsScriptErrorEvent errorevent;          errorevent.eventStructType = NS_EVENT;          errorevent.message = NS_SCRIPT_ERROR;          errorevent.fileName = fileName.get();          errorevent.errorMsg = msg.get();          errorevent.lineNr = report ? report->lineno : 0;          // HandleDOMEvent() must be synchronous for the recursion block          // (errorDepth) to work.          globalObject->HandleDOMEvent(presContext, &errorevent, nsnull,                                       NS_EVENT_FLAG_INIT, &status);        }        errorDepth--;      }      if (status != nsEventStatus_eConsumeNoDefault) {        // Make an nsIScriptError and populate it with information from        // this error.        nsCOMPtr<nsIScriptError>          errorObject(do_CreateInstance("@mozilla.org/scripterror;1"));        if (errorObject != nsnull) {          nsresult rv;          const char *category = nsnull;          // Set category to XUL or content, if possible.          if (docShell) {            nsCOMPtr<nsIDocShellTreeItem> docShellTI(do_QueryInterface(docShell, &rv));            if (NS_SUCCEEDED(rv) && docShellTI) {              PRInt32 docShellType;              rv = docShellTI->GetItemType(&docShellType);              if (NS_SUCCEEDED(rv)) {                category = docShellType == nsIDocShellTreeItem::typeChrome                  ? "chrome javascript"                  : "content javascript";              }            }          }          if (report) {            PRUint32 column = report->uctokenptr - report->uclinebuf;            rv = errorObject->Init(msg.get(), fileName.get(),                                   NS_REINTERPRET_CAST(const PRUnichar*,                                                       report->uclinebuf),                                   report->lineno, column, report->flags,                                   category);          } else if (message) {            rv = errorObject->Init(msg.get(), nsnull, nsnull, 0, 0, 0,                                   category);          }          if (NS_SUCCEEDED(rv))            owner->ReportScriptError(errorObject);        }      }    }  }  // Print it to stderr as well, for the benefit of those invoking  // mozilla with -console.  nsAutoString error;  error.Assign(NS_LITERAL_STRING("JavaScript "));  if (JSREPORT_IS_STRICT(report->flags))    error.Append(NS_LITERAL_STRING("strict "));  if (JSREPORT_IS_WARNING(report->flags))    error.Append(NS_LITERAL_STRING("warning: \n"));  else    error.Append(NS_LITERAL_STRING("error: \n"));  error.AppendWithConversion(report->filename);  error.Append(NS_LITERAL_STRING(" line "));  error.AppendInt(report->lineno, 10);  error.Append(NS_LITERAL_STRING(": "));  error.Append(NS_REINTERPRET_CAST(const PRUnichar*, report->ucmessage));  error.Append(NS_LITERAL_STRING("\n"));  if (status != nsEventStatus_eIgnore && !JSREPORT_IS_WARNING(report->flags))    error.Append(NS_LITERAL_STRING("Error was suppressed by event handler\n"));#ifdef DEBUG  char *errorStr = ToNewCString(error);  if (errorStr) {    fprintf(stderr, "%s\n", errorStr);    fflush(stderr);    nsMemory::Free(errorStr);  }#endif#ifdef PR_LOGGING  if (report) {    if (!gJSDiagnostics)      gJSDiagnostics = PR_NewLogModule("JSDiagnostics");    if (gJSDiagnostics) {      PR_LOG(gJSDiagnostics,             JSREPORT_IS_WARNING(report->flags) ? PR_LOG_WARNING : PR_LOG_ERROR,             ("file %s, line %u: %s\n%s%s",              report->filename, report->lineno, message,              report->linebuf ? report->linebuf : "",              (report->linebuf &&               report->linebuf[strlen(report->linebuf)-1] != '\n')              ? "\n"              : ""));    }  }#endif  // XXX do we really want to be doing this?  ::JS_ClearPendingException(cx);}