Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

How to Handle Errors in Minified JavaScript (for Rails Applications)

DZone's Guide to

How to Handle Errors in Minified JavaScript (for Rails Applications)

This article is a step-by-step guide to tracking your minified JavaScript asset errors inside a Rails application.

· Web Dev Zone
Free Resource

Discover how to focus on operators for Reactive Programming and how they are essential to react to data in your application.  Brought to you in partnership with Wakanda

Handling errors in the minified JavaScript portion of your Rails application can be frustrating. The exception and stack trace information that comes from the system is based on what may seems like an incomprehensible mess which doesn’t look like your original source code at all.

This article is a step-by-step guide to tracking your minified JavaScript asset errors inside a Rails application. We’ll also take a look at a few tools that can make your life easier when creating source maps.

Why We Need to Create Source Maps

In order to properly attribute errors to the original source code, you can create source maps of these JavaScript assets so that Raygun can properly attribute the stack trace and exception information to the correct locations in your original source code. This speeds up your issue resolution without fully exposing potentially vulnerable source code to the outside world.

What Are Minification and Asset Combining?

Minification is the process of removing all unnecessary characters in order to reduce the total file size of your JavaScript asset(s) without changing how the code actually functions. Minification speeds up the load time of your JavaScript assets, which can be incredibly useful in mobile applications and sites where bandwidth is limited or fast performance is paramount.

Combining assets speeds up and streamlines JavaScript asset loading by taking individual JavaScript asset files and placing them into a single file. This way, only one call is made on page load for the file as opposed to several calls to get all the individual files. The fewer back and forth requests a site has to make to load JavaScript files the better for site load times.

But Why Do I Need Source Maps?

When exceptions occur in minified/combined JavaScript assets the stack trace information is based on the line and column position of the code in the minified file.  Unfortunately this does not match up with the original source code and finding the true origin of the error can take an incredibly long time, especially in code bases with large amounts of JavaScript assets being compiled together.

Source maps provide you with the ability to decode how the files were combined and minified so that the exception stack trace information can be properly mapped back to the original source code.  This gives you the same ease of debugging while still allowing you to use these faster loading JavaScript assets.

What Things Will I Need to Set This Up?

Here is a list of things you should have ready to set up to implement source maps with your application:

  • The ability to install the UglifyJS2 NPM package on your local machine or production environment.
  • The ability to create a new Raygun application for the JavaScript portion of your application.

Setting Up Source Maps With Rails 4/5

Note: while Sprockets 4 is rumored to support source maps fully, version 3 (currently used by Rails 4/5) does not.

There are several different options when it comes to creating source maps to use with Rails. Some of these options involve completely shutting off the minification and combining in Sprockets while some go as far as completely removing Sprockets in favor of third party asset handlers like Grunt and Gulp. For the purposes of this post we are just going to turn off the minification and combining of Sprockets for non-standard assets (dev created versus things like jQuery) and then use UglifyJS2 to handle the minification of the remaining JavaScript assets.

Step 1: Download UglifyJS2

To get started download UglifyJS2 from NPM. Use UglifyJS2 from the command line later on to work with our custom JavaScript files.

npm install uglify-js -g


This will install UglifyJS2 from NPM globally on your machine (usually preferable).

Step 2: Prevent Sprockets From Grabbing Other Files

Next we need to make some changes to our Rails application’s default behavior.

Go to our application’s app/assets/javascripts/  directory and open up application.js.

Here we’ll remove the line that says //= require_tree .

//= require jquery
//= require jquery.turbolinks 
//= require jquery_ujs 
//= require turbolinks 
//= require bootstrap/dropdown 
//= require_tree .


This will prevent Sprockets from recursively grabbing other JavaScript files in our application’s app/assets directory  for minification/combining. This means that the other files like jQuery which are included here based on their installed gems will still be identified by Sprockets but anything else in the app/assets  folder will be ignored.

Step 3: Utilize Sprockets to minify loaded JavaScript

Once we’ve made the changes to application.js , we’ll use our terminal to run the rake assets:precompile  command. This will utilize Sprockets to both minifiy and combine the system loaded JavaScript files mentioned earlier.

To find out more about how Sprockets and the rake assets:precompile  task work, you can checkout the Rails Guide on the Asset Pipeline as well as the GitHub repo for Rails/Sprockets.

Many Rails experts recommend using this manual precompile process for production environment usage to have the assets loaded and ready to go from the start. In most Rails development environments the assets are recompiled each time they are requested or changed. While this works great for troubleshooting and visualizing the changes, it is a slow process especially for larger file sizes and for large numbers of files. Precompiling the assets for the production environment relies on the idea that the assets should not change often in production if they were properly tested and set up during development.

Note: the rake assets:precompile command will also do the same with your CSS/SCSS files and create a new minified/combined version. For the purposes of this post we’ll ignore these other files.

Step 4: Use the UglifyJS2 command

$ uglifyjs app/assets/javascripts/file_1.js app/assets/javascripts/file_2.js –source-map public/assets/mymin.js.map –o public/assets/mymin.min.jsa

Breaking this down:

$ uglifyjs app/assets/javascripts/file_1.js app/assets/javascripts/file_2.js  -> tells UglifyJS2 which files we’ll be working with as our sources (you can specify any number of space separated files here)

--source-maps public/assets/mymin.js.map  -> this tells the uglifyjs command that we want to create a source map for these files named mymins.js.map  and store it in the public/assets/  directory of your application.

Note:  You should name this file by adding the .map extension on to whatever you named your minified Javascript file to keep things organized


-o public/assets/mymin.min.js  -> Tells the uglifyjs command which directory and file you want the new minified/combined version of the source files to be located.

Note:  Naming this file with the .min.js  notation will help identify that it is the minified version for ease of use and tracking later. For more information on additional UglifyJS2 commands and options check out the official UglifyJS2 documentation.

Running this command utilizes the names/locations of your custom JavaScript asset sources to minify and combine the assets into a single file. Place a JavaScript comment at the bottom of the new file with the location of the source map, and create the source map itself.

Best practices for page load performance normally dictate that we should try to cut down the number of our JavaScript files being loaded but in this case we’re still going to get a net performance benefit having two files rather than three or more. One single file would be ideal but that would currently require completely turning off Sprockets and utilizing a third party service. This will help make it easier when handling errors in minified JavaScript for Rails applications.

How to Use Raygun for JavaScript Tracking

So we have our minified/combined files and our source map. One of the major benefits of usign Raygun in this way is that you don’t have to setup/create your own error tracking for both your Rails and JS app. Then you can view both apps in one location. You’ll need your Ruby on Rails application connected to Raygun before you start. (You can get a free 30 day trial here.)

The next step to handling errors in minified JavaScript for Rails applications is to set up a new application in Raygun for JavaScript tracking.

Step 1: Set Up a Separate Application in Raygun

The raygun4ruby provider only picks up exceptions originating from within the Ruby on Rails code of your application.  Exceptions thrown due to JavaScript issues would not be captured by this provider so setting up a separate application is necessary.

  • Once you are logged into Raygun, click on the ‘+’ symbol in the upper left corner of your browser window:
  • creating a new application in raygun

  • Click on ‘Create Crash Reporting application:’
  • create crash reporting application button

  • Enter in a name for your application and then click the ‘Next’ button:
  • raygun_cr_name_application

  • Click on ‘JavaScript’ in the list of languages:
  • raygun javascript language option

  • Following the directions given on the next screen to set up the Raygun JavaScript code snippets in the app/views/layouts/application.html.erb  file:
  • <!DOCTYPE html>
    <html>
      <head>
        <title>Your App</title>
        <%= csrf_meta_tags %>
        <script type="text/javascript">
          !function(a,b,c,d,e,f,g,h){a.RaygunObject=e,a[e]=a[e]||function(){
          (a[e].o=a[e].o||[]).push(arguments)},f=b.createElement(c),g=b.getElementsByTagName(c)[0],
          f.async=1,f.src=d,g.parentNode.insertBefore(f,g),h=a.onerror,a.onerror=function(b,c,d,f,g){
          h&&h(b,c,d,f,g),g||(g=new Error(b)),a[e].q=a[e].q||[],a[e].q.push({
          e:g})}}(window,document,"script","//cdn.raygun.io/raygun4js/raygun.min.js","rg4js");
        </script>
      </head>
      <body>
        <div class="container">
          <% flash.each do |key, value| %>
            <div class="alert alert-<%= key %>">
              <%= value %>
            </div>
          <% end %>
        </div>
        <script type="text/javascript">
          rg4js('apiKey', YOUR_API_KEY_GOES_HERE );
          rg4js('enableCrashReporting', true);
        </script>
      </body>
    </html>


    Note:  There is more information available in our documentation on our raygun4js provider should you need additional help, or contact our amazing Support Team.

    Step 2: Upload Your File

    Validate the source map you created earlier by uploading the file to your Source Map Validator.  If the source map is valid you should see the following:

    Image title

    Valid Raygun source map result

    Step 3: Head to the ‘source map center’

    Go back to your Raygun Crash Reporting dashboard and click on ‘JS source map center‘ under ‘Application settings‘ in the left side navigation menu:

     Image title

    Application settings inside Raygun’s dashboard

    Step 4: Upload your JavaScript files to Raygun

    By default Raygun will try to download JavaScript files from your site to create a mapped stacktrace. If they are not publicly accessible you can either upload them on this page or through an API endpoint:

    Option A – Upload via page

    Either drag and drop a file into the dialog window or click on ‘or select a file’ to open a file explorer window:

    raygun source map upload help solve errors for minified javascript for rails applications

    Option B – Upload via API endpoint

    raygun source map upload via api to help solve errors for minified javascript for rails applications

    Note:  Additional information regarding how to upload source maps and related files via the API endpoint are location in our Source Maps documentation.

    At this point your new Raygun application will be set up to properly attribute exceptions originating from the minified JavaScript asset files as if they were the original source files.

    Think we missed something important on how to handle errors in minified JavaScript for Rails applications?

    Share you feedback and suggestions on source maps in the comments below…

    Learn how divergent branches can appear in your repository and how to better understand why they are called “branches".  Brought to you in partnership with Wakanda

    Topics:
    javascript ,errors ,source maps ,raygun

    Published at DZone with permission of Jesse James, DZone MVB. See the original article here.

    Opinions expressed by DZone contributors are their own.

    THE DZONE NEWSLETTER

    Dev Resources & Solutions Straight to Your Inbox

    Thanks for subscribing!

    Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

    X

    {{ parent.title || parent.header.title}}

    {{ parent.tldr }}

    {{ parent.urlSource.name }}