Posted By

miohtama on 11/28/08


Tagged

event window print DOM Firefox click load exception firebug stacktrace onready failure silent traceback clicker


Versions (?)

Exception manager for DOM event handlers - no more silent failures


 / Published in: JavaScript
 

URL: http://blog.redinnovation.com/2008/08/19/catching-silent-javascript-exceptions-with-a-function-decorator/

It is utterly annoying when DOM event handler exceptions fail silently with Firebug. This package fixes this common problem.

  1. /**
  2.  * Enhanced Javascript logging and exception handler.
  3.  *
  4.  * It is utterly annoying when DOM event handler exceptions fail
  5.  * silently with Firebug. This package fixes this common problem.
  6.  *
  7.  * @copyright Copyright 2008 Twinapex Research
  8.  *
  9.  * @author Mikko Ohtamaa
  10.  *
  11.  * @license 3-clause BSD
  12.  *
  13.  *
  14.  *
  15.  * http://blog.redinnovation.com/2008/08/19/catching-silent-javascript-exceptions-with-a-function-decorator/
  16.  *
  17.  * Twinapex
  18.  *
  19.  * High quality web hackers for hire!
  20.  *
  21.  * http://www.twinapex.com
  22.  *
  23.  */
  24.  
  25. // Declare namespace
  26. twinapex = {}
  27.  
  28. twinapex.debug = {}
  29.  
  30. /**
  31.  * Print exception stack trace in human readable format into the console
  32.  *
  33.  * @param {Exception} exc
  34.  */
  35. twinapex.debug.printException = function(exc) {
  36.  
  37. function print(msg) {
  38. console.log(msg);
  39. }
  40.  
  41. print(exc);
  42.  
  43. if (!exc.stack) {
  44. print('no stacktrace available');
  45. return;
  46. };
  47. var lines = exc.stack.toString().split('\n');
  48. var toprint = [];
  49. for (var i = 0; i < lines.length; i++) {
  50. var line = lines[i];
  51. if (line.indexOf('ecmaunit.js') > -1) {
  52. // remove useless bit of traceback
  53. break;
  54. };
  55. if (line.charAt(0) == '(') {
  56. line = 'function' + line;
  57. };
  58. var chunks = line.split('@');
  59. toprint.push(chunks);
  60. };
  61. toprint.reverse();
  62.  
  63. for (var i = 0; i < toprint.length; i++) {
  64. print(' ' + toprint[i][1]);
  65. print(' ' + toprint[i][0]);
  66. };
  67. print();
  68. }
  69.  
  70.  
  71. /**
  72.  * Decorate function so that exceptions falling through are printed always.
  73.  *
  74.  * Returns a decorated function which will be used instead of the normal function.
  75.  * The decorated function has preplaced try ... catch block which will not let
  76.  * through any exceptions silently or without logging. Even though there is an
  77.  * exception it is normally throw upwards in the stack after logging.
  78.  *
  79.  * <pre>
  80.  *
  81.  * // myFunction can be bind to many events and exceptions are logged always
  82.  * myfunction = function()
  83.  * // crash here
  84.  * var i = foobar; // missing variable foobar
  85.  * });
  86.  * </pre>
  87.  *
  88.  * Then there are alternative usage examples:
  89.  *
  90.  * <pre>
  91.  *
  92.  * // Decorate function
  93.  * myfunction = twinapex.debug.manageExceptions(myfunction);
  94.  *
  95.  * // Bind with exception manager
  96.  * $document.clicker(twinapex.debug.manageExceptions(myfunction));
  97.  *
  98.  * // Run loader code with exception manager
  99.  * jq(document).ready(function() {
  100.  * console.log("Help pop up page wide init");
  101.  * twinapex.debug.manageExceptions(initHelpPopUpHandlers(document));
  102.  * });
  103.  * </pre>
  104.  *
  105.  *
  106.  * @param func: Javascript function reference
  107.  */
  108. twinapex.debug.manageExceptions = function(func) {
  109.  
  110. var orignal = func;
  111.  
  112. decorated = function() {
  113. try {
  114. orignal.apply(this, arguments);
  115. } catch(exception) {
  116. twinapex.debug.printException(exception);
  117. throw exception;
  118. }
  119. }
  120.  
  121. return decorated;
  122. }
  123.  
  124. // Don't use windows load handler for init()
  125. // since debug code might be called from other load handlers
  126. // Browser specific logging output initialization
  127. // - fake Firebug console.log for other browsers
  128. if(typeof(console) == "undefined") {
  129. // Install dummy functions, so that logging does not break the code if Firebug is not present
  130. var console = {};
  131. console.log = function(msg) {};
  132. console.info = function(msg) {};
  133. console.warn = function(msg) {};
  134.  
  135. // TODO: Add IE Javascript console output
  136.  
  137. // TODO: Add Opera console output
  138.  
  139. } else {
  140. // console.log provided by Firefox + Firebug
  141. }

Report this snippet  

You need to login to post a comment.