if (errorObject != nsnull) { nsresult rv = NS_ERROR_FAILURE;
const char *category = nsnull;  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"; } } }
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::nsGetDynamicScriptContext(cx, getter_AddRefs(context));  if (context) {    nsCOMPtr<nsIScriptGlobalObject> globalObject( dont_AddRef( context->GetGlobalObject() ) );    if (globalObject) {      nsCOMPtr<nsIScriptGlobalObjectOwner> owner;      if(NS_FAILED(globalObject->GetGlobalObjectOwner(getter_AddRefs(owner))) ||         !owner) {        NS_WARN_IF_FALSE(PR_FALSE, "Failed to get a global Object Owner");        return;      }      //send error event first, then proceed      nsCOMPtr<nsIDocShell> docShell;      globalObject->GetDocShell(getter_AddRefs(docShell));      if (docShell) {        static PRInt32 errorDepth = 0; // Recursion prevention        errorDepth++;        nsCOMPtr<nsIPresContext> presContext;        docShell->GetPresContext(getter_AddRefs(presContext));        if(presContext && errorDepth < 2) {          nsEvent errorevent;          errorevent.eventStructType = NS_EVENT;          errorevent.message = NS_SCRIPT_ERROR;          // 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"));        // XXX possible here to distinguish between XUL and content js?        // or could just expose setCategory and twiddle it later.        const char *category = "XUL/Content JavaScript";        if (errorObject != nsnull) {          nsresult rv = NS_ERROR_FAILURE;          if (report) {            nsAutoString fileUni;            fileUni.AssignWithConversion(report->filename);            const PRUnichar *newFileUni = fileUni.ToNewUnicode();            PRUint32 column = report->uctokenptr - report->uclinebuf;            rv = errorObject->Init(NS_REINTERPRET_CAST(const PRUnichar*, report->ucmessage), newFileUni,                                   NS_REINTERPRET_CAST(const PRUnichar*, report->uclinebuf), report->lineno,                                   column, report->flags, category);            nsMemory::Free((void *)newFileUni);          } else if (message) {            nsAutoString messageUni;            messageUni.AssignWithConversion(message);            const PRUnichar *newMessageUni = messageUni.ToNewUnicode();            rv = errorObject->Init(newMessageUni, nsnull, nsnull,                                   0, 0, 0, category);            nsMemory::Free((void *)newMessageUni);          }                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.AssignWithConversion("JavaScript ");  if (JSREPORT_IS_STRICT(report->flags))    error.AppendWithConversion("strict ");  error.AppendWithConversion(JSREPORT_IS_WARNING(report->flags) ? "warning: " : "error: ");  error.AppendWithConversion("\n");  error.AppendWithConversion(report->filename);  error.AppendWithConversion(" line ");  error.AppendInt(report->lineno, 10);  error.AppendWithConversion(": ");  error.Append(NS_REINTERPRET_CAST(const PRUnichar*, report->ucmessage));  error.AppendWithConversion("\n");  if (status != nsEventStatus_eIgnore)    error.AppendWithConversion("Error was suppressed by event handler\n");    char *errorStr = error.ToNewCString();  if (errorStr) {    fprintf(stderr, "%s\n", errorStr);    nsMemory::Free(errorStr);  }#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);}