Exception logging in JavaScript

  • Revision slug: Exception_logging_in_JavaScript
  • Revision title: Exception logging in JavaScript
  • Revision id: 169498
  • Created:
  • Creator: Sheppy
  • Is current revision? No
  • Comment fix grammar

Revision Content

{{template.Fx_minversion_header(3)}}

In versions of Firefox prior to Firefox 3, all JavaScript exceptions were always logged into the Error Console if they remained unhandled at the time execution returned back into C++ code. As a result, if, for example, C++ code called a JavaScript component, which threw an exception, that exception would be logged to the console at the time control was returned to the C++ caller.

This had the unintended consequence of errors that aren't serious problems being logged at length into the console. JavaScript code is often designed to throw exceptions to report a result condition back to the C++ caller. These might be perfectly normal circumstances, but the exceptions were dutifully logged nonetheless.

Exception reporting in Firefox 3

Firefox 3 improves reporting of unhandled exceptions by establishing a set of rules that determines whether or not an exception is worth reporting:

  1. Any methods annotated with the {{mediawiki.external('function')}} attribute in IDL that throw exceptions always report those exceptions into the Error Console.
  2. Any exceptions that are generated by XPConnect -- that is, those defined by {{template.Interface("nsIXPConnect")}} -- are always logged into the Error Console.
  3. The NS_NOINTERFACE error is never reported when returned by a JavaScript object's QueryInterface() method.
  4. The NS_NOINTERFACE error is never reported when returned by a JavaScript object's GetInterface() method.
  5. All other errors are reported when the last JavaScript frame on the stack returns to a C++ caller without handling the exception.

That last point deserves clarification. Consider this call chain:

Image:Exception-logging.png

Here we see C++ code calling a JavaScript component, which calls back into C++, which then calls back into JavaScript.

If JavaScript component 4 throws an exception, the exception is sent back up the call hierarchy until it reaches JavaScript component 2. If JavaScript component 2 doesn't handle the exception, the exception is then logged when control returns to C++ component 1.

In other words, all unhandled JavaScript exceptions that deserve reporting are thrown back up the call chain until control returns to the outermost C++ caller, at which point they get logged.

Forcing all exceptions to be logged

Sometimes you might actually want to see all exceptions get logged, regardless of what Firefox thinks of their likely importance.

There are two ways you can accomplish this.

First, you can set the environment variable <tt>MOZ_REPORT_ALL_JS_EXCEPTIONS</tt>. It doesn't matter what value you set this to (it can even be 0). If the variable exists, all exceptions will be reported.

Alternately, you can set the boolean preference <tt>dom.report_all_js_exceptions</tt>. If this preference is true, all exceptions will be logged.

See also

Revision Source

<p>{{template.Fx_minversion_header(3)}}
</p><p>In versions of Firefox prior to Firefox 3, all JavaScript exceptions were always logged into the <a href="en/Error_Console">Error Console</a> if they remained unhandled at the time execution returned back into C++ code.  As a result, if, for example, C++ code called a JavaScript component, which threw an exception, that exception would be logged to the console at the time control was returned to the C++ caller.
</p><p>This had the unintended consequence of errors that aren't serious problems being logged at length into the console.  JavaScript code is often designed to throw exceptions to report a result condition back to the C++ caller.  These might be perfectly normal circumstances, but the exceptions were dutifully logged nonetheless.
</p>
<h3 name="Exception_reporting_in_Firefox_3">Exception reporting in Firefox 3</h3>
<p>Firefox 3 improves reporting of unhandled exceptions by establishing a set of rules that determines whether or not an exception is worth reporting:
</p>
<ol><li> Any methods annotated with the <code>{{mediawiki.external('function')}}</code> attribute in IDL that throw exceptions always report those exceptions into the Error Console.
</li><li> Any exceptions that are generated by <a href="en/XPConnect">XPConnect</a> -- that is, those defined by {{template.Interface("nsIXPConnect")}} -- are always logged into the Error Console.
</li><li> The <code>NS_NOINTERFACE</code> error is never reported when returned by a JavaScript object's <code>QueryInterface()</code> method.
</li><li> The <code>NS_NOINTERFACE</code> error is never reported when returned by a JavaScript object's <code>GetInterface()</code> method.
</li><li> All other errors are reported when the last JavaScript frame on the stack returns to a C++ caller without handling the exception.
</li></ol>
<p>That last point deserves clarification.  Consider this call chain:
</p><p><img alt="Image:Exception-logging.png" src="File:en/Media_Gallery/Exception-logging.png">
</p><p>Here we see C++ code calling a JavaScript component, which calls back into C++, which then calls back into JavaScript.
</p><p>If JavaScript component 4 throws an exception, the exception is sent back up the call hierarchy until it reaches JavaScript component 2.  If JavaScript component 2 doesn't handle the exception, the exception is then logged when control returns to C++ component 1.
</p><p>In other words, all unhandled JavaScript exceptions that deserve reporting are thrown back up the call chain until control returns to the outermost C++ caller, at which point they get logged.
</p>
<h3 name="Forcing_all_exceptions_to_be_logged">Forcing all exceptions to be logged</h3>
<p>Sometimes you might actually want to see all exceptions get logged, regardless of what Firefox thinks of their likely importance.
</p><p>There are two ways you can accomplish this.
</p><p>First, you can set the environment variable <tt>MOZ_REPORT_ALL_JS_EXCEPTIONS</tt>.  It doesn't matter what value you set this to (it can even be 0).  If the variable exists, all exceptions will be reported.
</p><p>Alternately, you can set the boolean preference <tt>dom.report_all_js_exceptions</tt>.  If this preference is <code>true</code>, all exceptions will be logged.
</p>
<h3 name="See_also">See also</h3>
<ul><li> <a href="en/Error_Console">Error Console</a>
</li><li> {{template.Bug(415498)}}
</li></ul>
Revert to this revision