Advertisement
laurentbroy

Making JavaScript fail-fast

Nov 28th, 2014
175
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // This code make JavaScript fail-fast in developement and during smoke test.
  2. // Very useful to catch sneaky errors, and work hand-in-hand with fail-fast code
  3. // by making it much more "in your face".
  4.  
  5. // Fail-fast if an unhandled exception occur in JavaScript. This use a a very old API, and it
  6. //doesn't work with addEventListener, so we must go old school.
  7. window.onerror = function (message, file, line, column, error) {
  8.     // Chrome and Safari will give us a stack trace! But other browsers will not :(
  9.     var stackTrace = error && error.stack;
  10.    
  11.     showError(message, stackTrace);
  12. };
  13.  
  14. // Fail-fast if an external resource (tested with image) fail to load. Loading error event
  15. // don't bubble up the DOM, but we can catch them with a "capturing" listener
  16. // (the "true" argument at the end)
  17. document.addEventListener('error', function (event) {
  18.     // This has been created to test img element, but maybe we could do a || event.srcElement.href
  19.     // to catch error in stylesheet too (if that work). It may catch script errors also (not tested)
  20.     // Interestingly, the src property give us an absolute URL as resolved by the browser. Doing
  21.     // event.srcElement.getAttribute('src') give us the textual value of the attribute
  22.     var failedUrl = event.srcElement.src;
  23.  
  24.     // We capture the HTML of the parent node to find the misbehaving element more easily
  25.     var context = event.srcElement.parentNode.outerHTML;
  26.  
  27.     showError("Failed to load resource at url: " + failedUrl, context);
  28. }, true);
  29.  
  30. // In production, we would probably log the error instead
  31. function showError(message, stackTrace) {
  32.    
  33.     // The rest of the function will destroy the DOM, and that can cause
  34.     // subsequent error for asynchronous operation. So we only display the initial error.
  35.     // We could probably move this global to a variable scoped in a function
  36.     if (window.isDisplayingError) {
  37.         return;
  38.     }
  39.  
  40.     // We use jQuery to manipulate the DOM more easily, but a portable solution could use the DOM
  41.     // API directly. We style the element directly so that it display correctly even when the CSS
  42.     // doesn't load
  43.     $(document.body).html(
  44.         '<h1 style="color: red; padding: 20px 40px; margin 0">The application crashed</h1>' +
  45.         '<p style="padding:5px 40px;"><strong>' + message + '</strong></p>');
  46.  
  47.     if (stackTrace) {
  48.         var stackContainer = $('<pre style="padding:20px 20px; margin: 0 40px"></pre>');
  49.         $(document.body).append(stackContainer);
  50.         stackContainer.text(stackTrace);
  51.  
  52.     }
  53.  
  54.     // If you are like anyone, you will want to press backward, because the error look like an
  55.     // error that happened while loading a new page. But its not, you must refresh,
  56.     // not go back to the previous page!
  57.     $(document.body).append(
  58.         '<p style="padding:20px 40px;">' +
  59.         '   <a href="javascript:location.reload();">Refresh the page to continue</a>' +
  60.         '</p>');
  61.  
  62.     // Your page has crashed. Go back and fix your code!
  63.     window.isDisplayingError = true;
  64. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement