I am experimenting with catching Javascript errors with raven.js [1] (see the JS error logging RfC [2] for background; see T1345 [3] for a prototype for JS error logging). For various reasons, Javascript does not have a reliable way to install a global exception handler like e.g. PHP does with set_exception_handler(), so the standard way of doing this is to wrap modules into a try-catch block.
ResourceLoader already wraps minified scripts with something like
mw.loader.implement( "<module name>", function() { <module code> } );
so this could be changed to something like
mw.loader.implement( "<module name>", Raven.wrap( function() { <module code> } ) );
That means that the error logging module would have to be loaded by the time other modules are initialized, so I imagine it would have to become a startup module. My questions are:
1. do you see any problems with such a setup? The eventual goal would be to use this on the Wikimedia production cluster. 2. especially, is adding another startup script acceptable? (Adding raven.js to the jquery and mediawiki modules would mean a ~10% size increase.) 3. what would be the proper way of doing this from an extension? Add two new hooks for module wrapping and for defining additional startup modules?
[1] https://github.com/getsentry/raven-js [2] https://www.mediawiki.org/wiki/Requests_for_comment/Server-side_Javascript_e... [3] https://phabricator.wikimedia.org/T1345
On Thu, Dec 18, 2014 at 4:34 PM, Gergo Tisza gtisza@wikimedia.org wrote:
I am experimenting with catching Javascript errors with raven.js [1] (see the JS error logging RfC [2] for background; see T1345 [3] for a prototype for JS error logging). For various reasons, Javascript does not have a reliable way to install a global exception handler like e.g. PHP does with set_exception_handler(), so the standard way of doing this is to wrap modules into a try-catch block.
Chrome's profiling tools continue to flag try / catch blocks because they are ineligible for certain types of optimizations. We've discussed it before on this list, but I don't think we ever quantified the performance penalty (or even confirmed its existence), but I think that doing so should probably be a prerequisite to this change.
On Fri, Dec 19, 2014 at 9:35 PM, Ori Livneh ori@wikimedia.org wrote:
Chrome's profiling tools continue to flag try / catch blocks because they are ineligible for certain types of optimizations. We've discussed it before on this list, but I don't think we ever quantified the performance penalty (or even confirmed its existence), but I think that doing so should probably be a prerequisite to this change.
There are usually three ways exception handling can be slow: 1. entering/exiting the try block takes some time 2. throwing/catching an exception takes some time 3. the optimizer bails out on functions containing try/catch
Given that we are talking about wrapping modules, so the function containing the try/catch block is invoked once per module per page load, I don't think any of these should be relevant.
The first one will be more interesting for wrapping event handlers (something that would be also needed to replace window.onerror), since some event handlers like mousemove or scroll are invoked very frequently. I haven't found any claim that that is a significant performance hit, though; the usual claim is that you will be fine as long as you make sure that your try/catch block is not in the same function as any code that could be significantly improved by optimization.
E.g. bluebird has a pretty good discussion on optimization blockers: https://github.com/petkaantonov/bluebird/wiki/Optimization-killers This jsperf test also does not show much difference: http://jsperf.com/try-catch-performance-overhead
wikitech-l@lists.wikimedia.org