Page MenuHomePhabricator

Create a way to throw Warnings and Errors with proper tracing
Closed, DeclinedPublic

Description

If a native javascript method fails (eg. calling a member as a function on a non-object) there's an error thrown:

TypeError: Result of expression 'f.test' [undefined] is not a function.  [test.js:2]

But when a custom error is thrown (ie. "MediaWiki DeprecatedWarning: Function mw.legacy.sajax_init_object is deprecated" ) it will report no file/line number to the console or in some cases the filename and line number where the throw originates from, not where the function was called.

So the goal of this bug is to end up with something like:

    • short wrappers to avoid doing any throws directly in the code (would use or do something like jQuery.error )
  • mw.log (what it is now, simple dummy in production and console.log or mw.console in debug for logging messages)
  • mw.log.error and mw.log.warning for throwing stuff
  • mw.log.deprecated calls mw.log.warning with some magic stuff to know what was called and where it comes from
  • example of where it is defined

mw.legacy.sajax_init_object : function() {
mw.log.deprecated();

/* stuff */

}

  • example of where it would be triggered

function myGadget(){

var path = '...';
var xhttp = mw.legacy.sajax_init_object()
/* etc. stuff */
var foobar = getStuff();
mw.util.addPortletLink( foobar );

}

  • example of console output

{X} MWDeprecatedWarning: Use of sajax_init_object is deprecated [mygadget.js:3]
{X} MWSyntaxError: addPortletLink requires at least 3 arguments, 2 given [mygadget:49]

Links of interest:

Krinkle


Version: 1.17.x
Severity: enhancement

Details

Reference
bz27890

Event Timeline

bzimport raised the priority of this task from to Low.Nov 21 2014, 11:35 PM
bzimport set Reference to bz27890.
bzimport added a subscriber: Unknown Object (MLST).

The reason this is more than a simple request to create those methods is two things:

  • For one, javascript doesnt' have anything like FUNCTION, METHOD, LINE etc. in a function arguments.callee.name can be useful in some cases, but then again, we don't need the name of the function we're in (which would either be the deprecated function itself or the log wrapper)
  • Aside from the current function, the point is to trace where the current funtion was called *from*

I think this'll depend on the browser and such...

Firefox 4.0.1 w/ Firebug 1.7.1b console:

  • doesn't show file & line number for 'throw "test"' from a gadget.
  • does show file & line number for 'throw new Error("test")' from a gadget.

Chrome 10.0.648.205 w/ dev console open

  • does show file & line number for 'throw "test"' from a gadget.
  • does show file & line number for 'throw new Error("test")' from a gadget.

WMF'ing this for now. We can simply throw real exceptions can one can derive the callee from the stacktrace.

And in case we can to log only without interrupting the flow the common practice is to throw the error in a try-catch and log the Error object (which will have the stacktrace).