Thursday, September 18, 2014

Track.js and Non-Legitimate Errors

So I've been talking about Track.js, and how it collects JavaScript errors on your site in one tidy dashboard.  It also sends you a daily summary email.  

If all the errors it sends were legitimate, everything would be great.  Unfortunately, JavaScript errors can be caused by things totally beyond-your-control.  For example, here's a recent daily report we received:


And we notice a couple of things right off the bat:

  • Error messages can happen in all different languages, like Chinese.  If you can't read it, you probably have no hope of debugging it!  If this is a legitimate error, you just have to hope someone hits the same error in your native language.
  • Errors can be really vague.  "Invalid procedure call or argument" might just as well read "Ooops.  Something happened."
  • Errors can reference functions you've never seen before.  That syncBFPerformOnDOMChanged looks awfully strange.
Let's drill down to the error screen on that last one:



The fact that it happened in Mac OS X and Safari, but not any other browser, is a sign something might be amiss with a plugin.  If you plugin in that nasty function name into Google, you get almost no hits.   Well ... if it isn't in your code base, and it isn't in a third party library you're using, you can't do anything about this error. 

Fortunately, Track.js lets you filter out error messages that you can do nothing about.   Here's the code we use:

<script>
  window._trackJs = {
    onError: function (payload) {
       var messagesToIgnore = [
        new RegExp("ReferenceError: Can't find variable: dataKeys", "ig"),
       new RegExp("'fidoCallback' is undefined", "ig"),
new RegExp("addthis_(open|close)", "ig"),
new RegExp("Error calling method on NPObject","ig")
       ]
       for (var i=0; i < messagesToIgnore.length; i++) {
 if (messagesToIgnore[i].test(payload.message)) {
   return false;
 }
       }
       return true; 
     }
  }
</script>

That way, if we run into another problem that can do nothing about, we simply add another regular expression to this list.  You can also do more sophisticated checks like "If this happens in IE 6 or below, ignore it."

The bottom line: trying to get to 0 JavaScript errors in a public-facing site is not a good goal.  You never know what browser plugins are screwing around with your JavaScript, and you can't prevent that rogue user using Mosaic 0.1.  We've even seen BOTS that try to execute JavaScript code very naively, and barf up head-scratching errors.  

However, we've found the following strategy works great with Track.js:
  • If the error rate goes up sharply on a certain day, it's worth checking out.  Usually you can trace it back to a recent production change, or a particular edge case that just happened that day.
  • If someone independently reports an error your site, and they can give you a rough URL and timeframe, the Track.js dashboard can help you pinpoint it.  

Tuesday, July 29, 2014

Using Track:Js for a Legitimate Error

Using Track:Js, it's becoming clear there are two kinds of JavaScript errors:

  • Non-legitimate ones.  These are caused by buggy browsers or their respective plugins.  They usually don't affect site performance at all.
  • Legitimate ones.
The trick is deciding which category your error belongs to.   That's an art, and there are no hard and fast rules.  But there are some good heuristics, and Track:Js definitely helps you out there.  

I get a daily summary email from Track:Js with statistics and the top errors.  This morning I found:


The TypeError: 'undefined' is not an object error interests me a little.  It's a little generic, and generic errors are harder to track down.  But it "feels" like an error I'd make.  So I click on that error to get the hits in the Track:Js dashboard.

So here I got three errors around 5:11 on the same page, but with a legitimate modern browser.  (I do not consider WebThumb a legitimate one, nor ones like IE 5.)  So I pull it up in my browser of choice, Chrom on Ubuntu.  Sure enough the console says:



Which brings me to the most important differentiator of legitimate and non-legitimate bugs:
If it doesn't work in MY browser, it's a legitimate bug!
OK, that's kind of flippant.  But the next time I touch this page, I won't know if the bug is caused by my changes or not.  So I had better fix it.

Fortunately, Chrome gives nicer error messages than Safari, so I can Google this particular problem.  Searching for Cannot read property msie of undefined I get the following helpful post:

http://stackoverflow.com/questions/14793331/uncaught-typeerror-cannot-read-property-msie-of-undefined

And basically it confirms what I've run into before about jQuery.  Something is trying to use an old, deprecated-then-removed feature, and it looks like jquery-ui is the culprit.  Nicely, Track:Js tells me all the versions of the libraries that are loaded:

So we're trying to use jQuery 1.11 (a very new version at the time of this writing) with jQuery-UI 1.8 (which was released around 2010 or so).  I check the page source and find we're not loading jQuery-UI on our own.  Instead, it seems to be coming from the OpenTable script we're loading.  

After a few minutes, I find I can just pop in the jQuery Migrate plugin to make jQuery-UI 1.8 and jQuery 1.11 play nice together.  That's just:

<script type="text/javascript" src="https://code.jquery.com/jquery-migrate-1.2.1.min.js">

The error disappears from Chrome, so I release it to the wild.  Track:Js helped me in a couple of different ways here - not just identifying the error but providing me some good info on the context around it.  




Friday, July 25, 2014

Track:js: Hello World!

Like many web programmers, I wear two programming hats.  One hat is for the server-side, and whenever I make a mistake on the server side, bells and whistles go off, I get an email with a stakc trace, plus a Growl alert, a siren, and my cat arches his back and hisses.  I know right away when there is trouble in paradise.

The other hat is for the client-side.  Ugggh.  In JavaScript, no one will hear you scream.  When your little JavaScript snippet blows up, it leaves your page in a precarious half-useful state.  It might look OK but when you start trying to do stuff, things just don't work.  As a programmer you're used to this crap happening, and you start up FireBug or Developer Tools or what have you, more-or-less out of habit. You even do it on other people's sites.

But when your customers encounter an error, they immediately go to your competitor's site.  The problem has been around since Mosaic 0.1 beta.  You, as a programmer, need an alert when JavaScript blows up on the client's browser, wherever that may be.

Enter track:js. Think of it as an sniffer, logger and aggregator for all your site's JavaScript errors.   Pretty nice, but does it tamper with the user experience?  Do they need browser plugins, or the beta version of browser X that's not due until next year?  Nope.  Track:js does it's magic all with standard JavaScript.  That proves what you've known all along - JavaScript is tremendously powerful, even if it's  still a PITA.   Track:js seems to leverage it to the n'th degree.

We're total sceptics at the Cornell School of Hotel Administration, so we got a trial key and gave it a whirl.  We just popped this into our standard header:



And away we go.  After a few days we checked the handsome looking dashboard to see what's up.



It's a little bit of a shock to see your perfect website generating JavaScript errors that you've never heard about.  Surely it wasn't YOUR code, was it?  Did gremlins get hold of your Github account?  Ah well.  In the next day or two, we'll see what's up.

Oh, and all this nice stat gathering doesn't seem to affect performance.  The site is still nice and peppy.  So far, so good.

Sunday, March 15, 2009

This Server Best Displayed With Dojo

Can you believe it? There was a day when "This Site Best Displayed in [BROWSER]" was common on pages. Now you go to a page, you just assume that it speaks to the major browsers. It may look a bit different in IE, and there may be some browser sniffing going on the in the back room. (That back room might even be Dojo.) But you certainly don't make the user worry about it.

SOA had that compatability baked in. If your SOA server box said, "Best used with an IBM Database," what would be the point?

Here's the thing. All SOA servers can talk SOAP over HTTP. JavaScript can assemble SOAP packets, which are just strings after all, and send them via AJAX over the wire. That's a lot of overhead. If you control both of the endpoints - the browser and the SOA server - you'd be crazy not to use the "most native" transfer you can afford. That's what'll stop hourglasses on your CEO's browser.

In the Dojo Universe the most native file transfer format is REST and JSON. So it's a no-brainer, right? Get an SOA server that talks REST and JSON to your browser, and SOAP to the rest of the Service-Oriented World.

Not that simple, muh friend. REST is a buzzword-de-jour, and now every SOA server says they can do it. The ease of doing it is highly variable. If your Enterprise Service Bus talks XML across all the components, how do you translate the incoming and outgoing packets to query strings and JSON? If most SOA servers, the answer is "by writing code".

Ick! You mean I have to write a program for each and every translation? Well yeah. It may be a more specialized language like XSLT or XQuery, and hence easier than C++. But it's still code. And unlike translations between XML formats, which can be done with a visual editor, no one seems to have a visual XML-to-JSON designer bundled with their SOA server.

Let me be candid. I am the world's laziest programmer. Of course I want all the exception handling, logging, and asynchronous scheduling ... but I want to hand this over to the Business Analyst to do. I am too busy writing Dojo widgets. Those are fun!

So it's interesting. There are open source SOA servers that do what $100K/CPU SOA servers cannot. That's what I'll talk about next.

Wednesday, July 2, 2008

The SOA Supermarket

Dojo does a lot of things, but it can't pull data from just anywhere. The browser won't let it. That's the first heartbreaking lesson you learn in Ajax-land, your bar.com page can't send XHR requests directly to foo.com.

There are ways around it. The hacky-but-in-vogue method is JSONP, which says "run me this little JavaScript script at foo.com, and come back when you're done with the data." Yahoo and Google web services offer JSONP counterparts to their search services, and Dojo has really nice plumbing for calling them. We go over this in Mastering Dojo chapters 3 and 8. The bad news: a very small number of web services support JSONP.

A more universal solution is a proxy server. Your bar.com page will call the server, "Go fetch me this request at foo.com, will you?" bar.com, not subject to the cross-domain restrictions of a browser, will do that and serve back the results. And it's easy. One line of PHP nets you a proxy server. That's fine for starting out, but as you start taking advantage of more services, all the little details start becoming a PITA: security, routing, data conversion, etc.

And that's where Service Oriented Architecture (SOA) comes in. Here I don't mean just SOAP-based web services, but rather services as a way-of-life: loosely-coupled components from the Internet cloud, connected with orchestration glue in the middle. Your Dojo application shouldn't have to know about foo.com. Instead, it should know "answer this question and give me the answer in JSON format." The SOA server knows to ask foo.com, and convert the answer to JSON. And if foo.com is unreachable, it could contact anotherfoo.com for the same question. And so forth.

The point is SOA saves you coding on the middle tier. And let's face it - you really need to write less code there. Back in 1998, you could spend 20 hours a week on ASP, 20 hours a week on the database, let's say. Then Ajax comes along, and you need to do 15 hours of JavaScript (Dojo helps you here - it could be worse!) How do you squeeze 55 hours into a 40 hour work week? Eliminate your social life?

What I advocate is cutting ASP out altogether - adding 5 hours a week to moving logic back to the database tier, and 5 hours a week of SOA configuration. As you create more reusable Dojo components, you can cut 5 hours from your client-programming time. Voila! You're back to 40 hours, and you're building better apps.

So now your middle tier is a combined POWS (plain ol' web server) and SOA server. What do SOA servers look like? What do they do for you? And how do you choose from the veritable swamp of alternatives? I have some thoughts, which I'll share in the next post.

Tuesday, June 24, 2008

Dojo and The Incredible Shrinking Server

When you start using Dojo, your focus naturally shifts to the browser. The complexity you once shoved into server-side scripts begins to dissipate. JSP, ASP, Rails and PHP tasks like:

- Generating HTML based on dynamic data
- Validating and massaging user input
- Directing the navigation path

In a Dojo Rich Internet Application, some of this responsibility shifts to Dojo and JavaScript. For example, you now do validation and input massaging with dijit.Form elements. You generate HTML directly from the Dijit components themselves and from Dijit templates.

Some of the responsibility disappears altogether. Navigation from page to page, for example, doesn't matter if you only have one page. So the answer to the question "Where is the Dojo equivalent of Struts or CakePHP?" is "Nowhere."

It's fairly common for Dojo applications to slim down to pure HTML and JavaScript. Suddenly a circa 1995 web server is the right size for serving up your site. What's more, the web applications look like client-server apps from 1995, albeit more connected. Everything old is new again!

So what is the middle tier doing for you? Why not just connect your browser straight to your database and cut out the middleman, as it were? Well, you could. But don't go unplugging servers yet! There turns out to be lots of work you can do on the middle tier. And the nice part is a lot of this work can be done without programming. This is where Service Oriented Architecture comes in. I'll tell you what I mean in tomorrow's post...

Saturday, June 21, 2008

Instant Book Gratification

What's that? You promised this great new Ajax application in 2 weeks? You could probably use a good JavaScript toolkit and a good book on how to use it. May I suggest Dojo (http://www.dojotoolkit.org) and Mastering Dojo as the book? It's now available for electronic purchase at Pragmatic - http://www.pragprog.com. Printed copies purchased there will start shipping the week of June 23rd. Or you can buy them at Amazon the week after, or at your favorite bookstore the week after that.

Pragmatic Press books have their own style. If you've read one of their books (like the bestselling Agile Development with Rails), you know what I mean. They read like novels where the first chapters really grab you, then the subsequent ones unfold the topics evenly and gracefully. People have different learning styles, but I particularly like this format because it helps you learn the Way of Dojo - in other words, what concepts hold it all together. The more you learn the concepts, the less you need to memorize. Sounds good, eh?