Exception manager for DOM event handlers - no more silent failures


/ Published in: JavaScript
Save to your folder(s)

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


Copy this code and paste it in your HTML
  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. }

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

Report this snippet


Comments

RSS Icon Subscribe to comments

You need to login to post a comment.