Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Debug the Web 101

Debug the Web 101

Useful Javascript Debugging Techniques in production environment.

4cf1fe8b2884598dc23e6bb73b9d65db?s=128

Ankur Agarwal

March 31, 2013
Tweet

Transcript

  1. ANKUR AGARWAL DEBUG THE WEB 101

  2. Who do I do ? Twitter @Agarwal_Ankur Github @devilankur18

  3. Web is Evolving

  4. So Code Breaks

  5. And when it breaks

  6. None
  7. Case Study

  8. So how to debug ?

  9. window.onerror

  10. 1. Error Message 2. Line No 3. Filename For the

    same origin only* * Some browsers provide information for cross origin as well Provides
  11. 1. Callstack missing 2. Character no. missing 3. Doesn't work

    for Cross origin scripts Challenges
  12. None
  13. try catch

  14. try { // Some code } catch (e) { //

    Character No // Stack Traces // Works for cross origin } Its simple to use
  15. Challenges 1. Need to add extra code 2. How to

    use with existing code and libraries ? 3. Performance Tradeoff
  16. None
  17. function wrap(func) { function wrapped() { try { return func.apply(this,

    arguments); } catch (e) { console.log(e.message); throw e; } } return wrapped; } A simple wrapper
  18. function track (object) { for (var fn in object) {

    if (typeof fn === "function") { object[fn] = wrap(fn); } } } A object wrapper
  19. var obj = { a : 1 b : 2

    foo: { return "Hello World!" }, bar: { throw new Error("Hello World!"); } } track(obj); obj.foo(); // return "Hello World!" obj.bar(); // throws exception Example
  20. window.console

  21. Challenges 1. Old IE doesn't have console 2. Console object

    is unavailable until opened 3. Don't want to throw logs in production
  22. None
  23. if( (window && !window.console) || isProduction() ) { var apis

    = ['log','info','warn','error','assert','dir', 'clear','profile','profileEnd'], g, api, container = window.console = {}; for (g = 0; g < apis.length; g++) { api = apis[g]; container[api] = function () {}; } } function isProduction() { // Some logic return document.location.hostname !== "localhost"; } A simple wrapper
  24. Challenges 1. Collect the error logs in production 2. Developers

    don't have access to users browsers
  25. None
  26. report errors

  27. function report(message, url, linenumber) { if (window.XMLHttpRequest) { var xhr

    = new XMLHttpRequest(); var scripturl = "http://yourdomain.example.com/report"; var log = linenumber + message + url; xhr.open("POST", scripturl); xhr.setRequestHeader("Content-Type", "text/plain; charset=UTF-8"); xhr.send(log); } } function reportEx(ex) { // Extract Info from exception var info = extract(ex); report(info.message, info.url, info.lineno); } Some Helpers
  28. window.onerror = report; // With try-catch try { // Some

    code } catch (e) { // Character No // Stack Traces // Works for cross origin reportEx(e); } Usage
  29. async functions

  30. function asyncTrack(fnName) { var originalFn = window[fnName]; window[fnName] = function

    AsyncTrackingWrapper() { // Make a copy of the arguments var args = _slice.call(arguments); var originalCallback = args[0]; if (typeof originalCallback === "function") { args[0] = wrap(originalCallback); } // IE < 9 Hack if (originalFn.apply) { return originalFn.apply(this, args); } else { return originalFn(args[0], args[1]); } }; }; asyncTrack('setTimeout'); asyncTrack('setInterval');
  31. instrument functions

  32. Simple Helpers function instrumentFunction(context, functionName, callback) { context = context

    || window; var original = context[functionName]; context[functionName] = function instrumented() { callback.apply(this, arguments); return context[functionName]._instrumented.apply( this, arguments); }; context[functionName]._instrumented = original; }
  33. Simple Helpers function deinstrumentFunction(context, functionName) { if (context[functionName].constructor === Function

    && context[functionName]._instrumented && context[functionName]._instrumented.constructor === Function) { context[functionName] = context[functionName]. _instrumented; } }
  34. debug frameworks

  35. jQuery // All methods of jquery will be wrapped track(jQuery);

    // A simple helper to track ajax errors $(document).ajaxError( function(event, jqXHR, ajaxSettings, thrownError) { // Report this error report(thrownError, null, null); });
  36. Ember.onerror = reportEx; Emberjs

  37. None
  38. Q & A

  39. And we are hiring Send your resume / github profiles

    to ankur@debuggify.net Website: www.debuggify.net/career
  40. Thank you For More Tips & Tricks Follow us on

    Twitter @D3buggify Signup for debugging your production code www.debuggify.net/signup