Page MenuHomePhabricator

Find a way to detect unhandled jQuery promise rejections in VisualEditor
Open, Needs TriagePublic

Description

Steps to reproduce:

  1. Run this code in Chromium or Firefox with the debugger open:
var prom = Promise.resolve();
prom.then( function () {
        console.log( 'A' );
} ).then( function () {
        console.log( 'B' );
} ).then( function () {
        throw new Error( 'Foo' );
} ).then( function () {
        console.log( 'C' );
} ).catch( function ( ex ) { 
        console.log( 'Caught', ex );
} ).then( function () {
        console.log( 'D' );
} ).then( function () {
        throw new Error( 'Bar' );
} ).then( function () {
        console.log( 'E' );
} ).then( function () {
        console.log( 'Caught', ex );
} );
  1. Observe that the debugger does nothing special with the handled rejection Foo, but it reports the unhandled rejection 'Bar' (either breaking on it or logging it to console).
  1. Now, try the same again but replacing the native Promise.resolve() with jQuery's $.Deferred().resolve().

Expected behaviour:

Error detected: the debugger draws attention to the unhandled promise rejection Bar (but not the handled promise rejection Foo), whether in the same way as native promises or in some other way.

Observed behaviour:

Silent failure: the debugger does nothing special with the unhandled promise rejection Bar (other than the manually inserted console.log statement).

Discussion

Silently failing unhandled jQuery promise rejections are causing trouble in VisualEditor development. They occur fairly frequently, and waste developer time either through extra bug-hunting distraction or (in the worst case) deployed errors. The obvious options are:

  • Some general, clean mechanism at the jQuery level. I tried a few things with @Krinkle and it seems this may be infeasible right now. A fully general unhandled promise rejection event at the jQuery level has been requested and declined: https://github.com/jquery/jquery/issues/2908 .
  • Some clever hack that works for our purposes. (Perhaps hacking the jQuery code to mirror jQuery promises with native ones, in debug mode only?)
  • Give up: just try to detect unhandled promise rejections by heroically good code review.

Details

Related Gerrit Patches:

Event Timeline

dchan created this task.Sep 21 2019, 11:04 AM
Restricted Application added a subscriber: Aklapper. · View Herald TranscriptSep 21 2019, 11:04 AM

Change 539074 had a related patch set uploaded (by Divec; owner: Divec):
[VisualEditor/VisualEditor@master] WIP POC DONTMERGE NOREALLYDONT make jQuery promises fail loudly

https://gerrit.wikimedia.org/r/539074

JTannerWMF added a subscriber: JTannerWMF.

I am moving this to Current Work since @dchan is working on it

Tgr added a subscriber: Tgr.Thu, Nov 28, 10:59 PM

You can override jQuery.Deferred.exceptionHook. That will register all exceptions, not just unhandled ones (exceptions/errors only, not rejections), which is noisy but might still be useful for debug mode.