tag:blogger.com,1999:blog-81797194088042467852024-03-05T10:21:59.365+05:30{errorception} blogRakesh Paihttp://www.blogger.com/profile/05275465816567723588noreply@blogger.comBlogger48125tag:blogger.com,1999:blog-8179719408804246785.post-47809600944656287682015-02-16T20:13:00.000+05:302015-02-16T20:13:52.037+05:30Comment on Errors<p>I've just pushed a build that lets you comment on your errors. (Finally!)</p>
<p>I'll admit, I've been very sceptical about adding this feature to Errorception. Thing is, this moves Errorception closer to being a bug <em>management</em> tool, whereas I just want it to be a bug <em>reporting</em> tool. You already use a bug management tool internally, and there's no point trying to replicate those features in Errorception. It only creates confusion for you.</p>
<p>However, there's a case to be made for leaving comments on errors within Errorception without having to put it into your bug reporting system. These are usually for when you want to leave a note for yourself and your team members, without the need to create an issue in your bug reporting system. In such a case, it could make sense to tack it along with the error in Errorception, rather than in your bug reporting system.</p>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEij9CKbVCBf4tLp9FMb-rnqMnojSlI0P6vGKVEzDYFpwG_F2ApvYMAfds5_HooetSUkn__1fDTODgtqw4MPgbTsEMFT2kjNfbA83qxkSMGwZNMrZRfmexgP3NTonOuKVZsyjeVw7qSuvqKS/s1600/comment-screenshot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEij9CKbVCBf4tLp9FMb-rnqMnojSlI0P6vGKVEzDYFpwG_F2ApvYMAfds5_HooetSUkn__1fDTODgtqw4MPgbTsEMFT2kjNfbA83qxkSMGwZNMrZRfmexgP3NTonOuKVZsyjeVw7qSuvqKS/s697/comment-screenshot.png" /></a></div>
<p>Building commenting systems is a complex task, and I'm certainly not considering this feature-complete. That said, the current implementation is fast, minimal, and it "just works", in the typical Errorception style. (See how I let that last bit sneak in there?)</p>
<p>Let me know what you think!</p>Rakesh Paihttp://www.blogger.com/profile/05275465816567723588noreply@blogger.com0tag:blogger.com,1999:blog-8179719408804246785.post-13251617572186372222014-11-05T20:57:00.000+05:302014-11-05T20:57:48.589+05:30Enabling CORS on Amazon CloudFront with S3 as your Origin Server<p>Today I was debugging a customer's CloudFront setup to ensure that they were supporting CORS correctly. <a href="http://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html">Amazon has documented the process</a>, but the docs seem to be structured to work as a reference rather than a how-to. I thought I'd document what I had to do to get things working right, so that this serves as a starting point for others to get set up.</p>
<p>As you probably know, <a href="http://blog.errorception.com/2012/12/catching-cross-domain-js-errors.html">enabling CORS is important if you want to catch cross-domain JavaScript errors</a>. If you are using CloudFront as a CDN, you are most likely using a different domain (or subdomain) to serve your files, and will need to set up CORS at CloudFront.</p>
<p>The bulk of the surprises with setting up CORS with CloudFront are with configuring S3 correctly. This is the typical setup for most people (CloudFront using S3 as their Origin Server), so you'll probably have to deal with this first.</p>
<h3>Configuring S3</h3>
<p>S3 has this unnecessarily complicated "CORS configuration" that you need to create. Here's the steps to get that right:</p>
<ul>
<li>Log into your <a href="http://console.aws.amazon.com/s3/home">AWS S3 console</a>, select your bucket, and select "Properties". S3 CORS configurations seem to apply at the level of the bucket, and not the file. I have no clue why.</li>
<li>Expand the "Permissions" pane, and click on "Add CORS configuration" or "Edit CORS configuration" depending on what you see.</li>
<li>You should already be provided with a default permission configuration XML. (Seriously, Amazon? 2014? XML?) If not, use the following XML to get started.
<pre><code><?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
</CORSConfiguration>
</code></pre>
<p>You should look at <a href="http://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html">Amazon's docs</a> to see what this configuration means.<p>
<p>In the course of this debugging exercise, I discovered the hard way that Amazon's XML parser cares about the <code><?xml ?></code> declaration, and the <code>xmlns</code> on the root node. If you omit these, Amazon will fail silently, showing you a happy looking green tick! (Can you imagine how hard it was to figure this out?)</p></li>
<li>Once you've saved the configuration, go get a coffee (or other preferred poison) while you wait for S3 to be one with your new configuration, and really internalise it's true meaning. (It takes a couple of minutes. Some sort of caching, I guess.)</li>
<li>Test if everything's looking right. This really tripped me up. Turns out, for a really complicated reason, you can't simply hit a URL in your S3 bucket from within your browser and check the "Network" tab in your dev tools. That would be too easy. No, you need to ensure that you specify certain extra headers in your request. Now, it turns out that browsers send this with CORS requests anyway, so you are covered in the real-world, but it's crazy that the dev-experience for the common case isn't what you'd expect. You could use a tool like curl to specify the additional headers needed for a "correct" CORS request:
<pre><code>$ curl -sI -H "Origin: example.com" -H "Access-Control-Request-Method: GET" https://s3.amazonaws.com/bucket/script.js
HTTP/1.1 200 OK
Date: Wed, 05 Nov 2014 13:37:20 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Access-Control-Max-Age: 3000
Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
Cache-Control: max-age=604800, public
...snip...
</code></pre>
You should see the "Access-Control-Allow-Origin: *" header, and the "Vary: Origin" header in the output. If you do, you're golden.</li>
</ul>
<p>With that, you are almost done! CloudFront's configuration is a piece of cake in comparison.<p>
<h3>Configuring CloudFront</h3>
<ul>
<li>Go to your <a href="https://console.aws.amazon.com/cloudfront/home">CloudFront console</a>, select your distribution and go to the "Behaviors" tab.</li>
<li>You should already have a "Default" behavior listed there. Select it and hit "Edit".</li>
<li>Under the "Whitelist Headers" section, navigate their clunky UI to add the "Origin" header to the whitelist.</li>
<li>Save, get another coffee, and wait for this to propagate through CloudFront's caches. This will take some time.</li>
<li>Test! Again, you will have to use the process above to make sure you are flipping the right switches within Amazon. That is, use curl (or some HTTP client), and ensure that you specify the extra headers. You should see the "Access-Control-" headers in the response.</li>
</ul>
<p>There you go! That should get you set up. I can't believe Amazon has made it so complicated to essentially send an additional HTTP header. Well, regardless, I hope this post helps you get set up correctly.</p>
<p>You will also need to modify your script tags to ensure that you catch JS errors correctly. You can read more about that <a href="https://errorception.com/docs/cors">in the docs</a>.</p>
<p>Not catching JS errors yet? You should really give <a href="https://errorception.com/">Errorception</a> a shot.</p>Rakesh Paihttp://www.blogger.com/profile/05275465816567723588noreply@blogger.com12tag:blogger.com,1999:blog-8179719408804246785.post-35397316868462916372014-10-08T18:02:00.000+05:302014-10-08T18:02:01.869+05:30Preventing Flooding<p>Flooding in the IRC sense, that is. Not the global warming sense, of course. Because global warming isn't real, amirite?</p>
<p>We've all encountered this in the past. Your logs reveal that some user is using a rogue plugin, and the plugin throws errors in a loop. Hundreds, if not thousands of errors get sent to Errorception in a short period of time. This eats into a significant chunk of your daily rate limit, without actually giving you quality data. Some people end up exhausting their daily rate limit in just a few seconds because of this!</p>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsYiRGnPomvdI1peT2u_Kpwd2Ymf43VGLVZNwYsSpd7VXZ-BP_j1MMdq8OozUAyfcyoXBiEz0uHNIkwcOf9-9VMd4TGOwS4_ORYpXzoLq0Cpd6e7xHyiLc3XPBh0A42ziuh2i0tTsHiNpq/s1600/ratelimit.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsYiRGnPomvdI1peT2u_Kpwd2Ymf43VGLVZNwYsSpd7VXZ-BP_j1MMdq8OozUAyfcyoXBiEz0uHNIkwcOf9-9VMd4TGOwS4_ORYpXzoLq0Cpd6e7xHyiLc3XPBh0A42ziuh2i0tTsHiNpq/s1600/ratelimit.png" /></a></div>
<p>No more! Errorception now imposes a per-user rate limit. This is an arbitrary limit to try to separate the wheat from the chaff. Currently, the per-user rate limit is set to 50 errors per 250ms.</p>
<p>Here's how it works: If the user generates more than 50 errors within 250ms, that's some serious error generation going on. Errorception takes 50 of those errors and posts them to the server, just so that you are informed about the problem. Errorception then goes ahead and flags that user as being "banned" until the page unloads. This means that no more errors will be posted to Errorception from this user while he's on that page. That way, you are informed about the problem since 50 errors got posted, but your daily rate-limit isn't completely eaten into.</p>
<p>There's another angle to this problem that has always worried me: If users are generating so many errors in such a short time, and Errorception then tries to process this large number of errors in the browser even if just to upload them, there's bound to be a perceptible sluggishness. That simply isn't cool. Errorception should never cause any perceptible performance lag. Now, with this fix, when a user is "banned", Errorception completely steps out of the way. That way, even though the user is probably stuck generating errors in a loop, at least Errorception isn't causing any additional performance lag. One more feather in the cap for high performance!</p>
<p>As always, suggestion and feedback always welcome.</p>Rakesh Paihttp://www.blogger.com/profile/05275465816567723588noreply@blogger.com2tag:blogger.com,1999:blog-8179719408804246785.post-7700126051620693072014-09-19T19:23:00.001+05:302014-09-20T07:35:36.861+05:30Fresh Coat of Paint<p>Errorception just got a redesign! <a href="https://errorception.com/">Give it a look</a>! I'm particularly excited about the <a href="https://errorception.com/docs">revamped docs</a>.</p>
<p>Not only is the new site a huge visual improvement, it's also far more functional and accessible, and much more secure thanks to a very strict Content Security Policy (CSP). It also has a fully buzzword-compliant front-end stack now, while maintaining the blazing performance of a very light-weight site.</p>
<p>The <q>logged-in</q> area of the site hasn't been redesigned yet, but there has to be something for next time, right? ;)</p>
<p>Let me know what you think! Feedback welcome, as always.</p>
Rakesh Paihttp://www.blogger.com/profile/05275465816567723588noreply@blogger.com0tag:blogger.com,1999:blog-8179719408804246785.post-64442952531099054472014-08-26T21:22:00.001+05:302014-08-26T21:22:36.116+05:30Private Source Maps<p>
Since the <a href="http://blog.errorception.com/2014/06/source-maps-are-here.html">launch of source maps</a>, you have been asking for a way to support source maps without having to make all your code public. Today I'm glad to announce private source map support in Errorception.
</p>
<p>
Rather than explain how the feature works, I shall take you through the thought process behind private source maps support. It has taken 2 months to fine-tune the experience. I was actively working with a bunch of people in a private beta for this feature. (Thanks to you fine folk. You are awesome!)
</p>
<p style="background: #FCFCE1; border: 1px solid #fc0; padding: 10px;">
<strong>A quick primer</strong>: Source map files, generated by your minifier, contains a mapping between your original source code and your minfied code. Your source map files are linked to from within your minified code, using a <code>//#sourceMappingUrl=...</code> comment in your minified code, inserted by your minifier. The source map file doesn't contain the original source code itself — just the mappings. Instead, the source map file links to your source code, which a consumer (like Errorception, or your browser's dev tools) will have to fetch separately.
</p>
<h2>The First Cut</h2>
<p>
When I had launched source map support two months ago, I had already written the code for private source maps too. The way I intended it to work was that I'd ask you to upload your source map files and your source code to Errorception as part of your deploy script. I wasn't sure how everyone would take to the idea of making an API call from within their deploy script, so I decided to start a private beta and work with a few select people directly to see what their experience would be.
</p>
<p>
However, everyone disliked the idea of making API calls from their deploy scripts. Every single one of them! Here's the big reasons:
</p>
<ul>
<li>It introduces a remote network dependency in the deploy script. This means that the deployment's success or failure depends on a third-party service (Errorception in this case), and on the network. This simply isn't a good idea.</li>
<li>If, for some reason, the API call fails, it will cause inconsistency in data at Errorception's end. It's not just that source maps won't work, it's worse than that — source maps will point to the wrong location in your files! That's misleading, and actively inhibits easy debugging. Not good at all.</li>
<li>Making API calls isn't really the simplest of things to do, especially when you have to do it from a deploy script. You'd first have to prepare your <q>bundle</q> by zipping up your files (which is likely to be a pretty big zip), then send it across to Errorception using some HTTP client, after you've figured out how to do multipart uploads. To deal with failures, you'd also have to implement some kind of retry mechanism. It doesn't have to be this complicated.</li>
<li>As an aside, this is also tremendously wasteful. Unless your errors are all over your code-base, Errorception doesn't need all your files at all. The bulk of the zip you'll have uploaded won't be useful for debugging at all, but there's no way to know which parts are needed beforehand.</li>
</ul>
<h2>Errorception's Crawler</h2>
<p>
Instead of asking you to upload your source maps and source code to Errorception, we decided that you could instead upload the files to your own web server/CDN. This is much more easy to do, considering that your deploy script already does this with your built code. It also eliminates the external network request to Errorception at deploy-time, which makes your deployment script simpler and far more reliable.
</p>
<p>
Errorception already has a crawler that crawls your site to get the required JavaScript files, needed both for the <a href="http://blog.errorception.com/2014/06/heres-your-error.html">code view</a> and for <a href="http://blog.errorception.com/2014/06/source-maps-are-here.html">source maps support</a>. This crawler is actually pretty powerful, and has evolved quite a bit within its few months of existence. It has baked into it a couple of really cool ideas to ensure consistency of data. This ensures that Errorception can always show you the correct version of the file that caused the error, even if the file has since changed with newer deployments. It is also resilient to network failures, retrying failed requests intelligently, and retroactively updating existing errors with the file. (Building this has been pretty crazy engineering-wise — heck, I even had to create a versioned file store to manage file versions correctly!)
</p>
<p>
Let's say you have an error in one of your script files. Errorception's crawler <a href="https://github.com/errorception/source-mapping-url">parses your JavaScript file</a> to look for the <code>//#sourceMappingUrl</code> pragma comment. If it finds this comment, it already has everything it needs to crawl your source map files and your source code. This is how <q>public</q> source maps work already.
</p>
<p>
However, many people would rather not have that <code>//#sourceMappingUrl</code> comment in their code. That's because this comment is the one link to all of your code, and will let anyone with a browser access the original unminified source code.
</p>
<h2>Private Source Maps</h2>
<p>
If this <code>//#sourceMappingUrl</code> comment is removed from your minified file, your source maps are now effectively private. This is because no one can know where you've put your files if there isn't a link pointing them to them. HTTP doesn't have any discovery mechanism built in, and a <q>secret</q> path is just as unguessable as a password, since no one else knows the secret. (This assumes that you don't have directory listing turned on.)
</p>
<p>
So, this is how <q>private</q> source maps work in Errorception: You specify a secret folder name in Errorception's Settings > Source Maps. This secret folder should be as unguessable as you would want a password to be. Then, modify your build/deploy script such that Errorception can find your source map on your web server by constructing a path that incorporates this secret folder. (More about this below.) Once the crawler gets your source map file, it has everything it needs to figure its way about your code.
</p>
<h2>Examples</h2>
<p>
Here's how Errorception uses your secret folder to discover your source map file: Let's say an error occurred in your script at <code>http://example.com/script.js</code>, and you've specified your secret folder to be <code>deadbeef</code>, Errorception will look for the source map at <code>http://example.com/deadbeef/script.js.map</code>. That is, it looks inside a secret folder (which is expected to be a sibling of the script file), for a file that has the same name as the script file with a <code>.map</code> appended to it.
</p>
<p>
To give you another example, if the error was in <code>http://example.com/a/b/c/script.js</code> and you specify your secret folder to be <code>secret</code>, Errorception will look for the source map at <code>http://example.com/a/b/c/secret/script.js.map</code>.
</p>
<p>
All of this sounds complicated, but it really isn't. In fact, in most cases, it will simply be one or two lines in your deploy script — to strip the <code>//#sourceMappingUrl</code> comment, and to copy your source map files and original source code to the secret folder. Doing stuff like copying and modifying files is exactly what deploy scripts are good at, so it plays to the strengths of the deploy script too.
</p>
<h2>But this isn't really private at all</h2>
<p>
Yes, in a sense, this is really only security by obscurity. However, it is security by obscurity in the same way that passwords are security by obscurity. As with good passwords, a good folder name would be just as unguessable. Since it is impossible to discover anything over HTTP if you don't explicitly link to it, unwanted access to your source code should be near-impossible.
</p>
<p>
That said, I can see how you might be worried that all your files are still public. I'm open to consider even more stringent security, if you like. Feel free to get in touch. However, like I said, you shouldn't have to worry about it in the first place.
</p>
<p>
Also, Errorception turned three last week. Drink one for Errorception! Cheers!
</p>Rakesh Paihttp://www.blogger.com/profile/05275465816567723588noreply@blogger.com7tag:blogger.com,1999:blog-8179719408804246785.post-60767300969510313592014-06-24T13:58:00.000+05:302014-06-24T13:58:23.711+05:30Source Maps Are Here!<p>
In <a href="http://blog.errorception.com/2014/06/heres-your-error.html">the previous blog post</a> I talked about the exciting new feature of highlighting exactly where the error is, <em>in your code</em>. The fact that this is even possible to do externally, is the kind of stuff that distinguishes JavaScript from all other languages. It is why Errorception has this singular focus on JavaScript.
</p>
<p>
This post is to highlight one more such feature — source maps.
</p>
<p>If you have errors in your minified code and Errorception's crawler discovers a <a href="http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/">source-map</a> file associated with your code, it downloads the source-map file and your associated original source files, and versions & saves it in Errorception's file store. After that, all the goodness of pointing out the error isn't just applied to your minified file, but also to your original source-code.
</p>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhO-loME4kDnYNozgDAL77rnBcVmrvnoqTRYDFsS8znQBxrgPWciXlZ3dIatgu3I-Wza2SLkSgtDE4S4EVyCHpJ5nH4NA4q0uiogZ61pDFA2pr0r3_IWqVQWgvguV8oYiO1VVLqZo9ICKfJ/s1600/mapped.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhO-loME4kDnYNozgDAL77rnBcVmrvnoqTRYDFsS8znQBxrgPWciXlZ3dIatgu3I-Wza2SLkSgtDE4S4EVyCHpJ5nH4NA4q0uiogZ61pDFA2pr0r3_IWqVQWgvguV8oYiO1VVLqZo9ICKfJ/s640/mapped.jpg" /></a></div>
<p style="text-align: center; font-size: 0.9em; color: #999; font-style: italic;">Mapped! Showing you the error in your un-minified source!</p>
<p>Errorception shows you exactly where the error is in your original, unminified source-code. Not just that, it does all of this automatically, and across all your stack frames! Isn't that just awesome?</p>
<p>You just need to make your source-map file available, and Errorception will do the rest. The tweaks needed to your build script are real simple too — it's usually <a href="https://github.com/mishoo/UglifyJS2#usage">just</a> a <a href="http://requirejs.org/docs/optimization.html#sourcemaps">flag</a> in <a href="https://developers.google.com/closure/compiler/faq#sourcemaps">most</a> minifiers.</p>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiJrJniZk8NideDzovClMYmnNoXqX5R9KxvvcFdrNywhM5Qr71aKVXZ1rlEdlZTXRT_L-KiKcHdNlFvYTyjsPpJy_ApMb_RVj_uxvtDckHEuL2ZGgpqZtPwLr0aQ4AxhgzF2FI4UpcM7wi/s1600/minfied.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiJrJniZk8NideDzovClMYmnNoXqX5R9KxvvcFdrNywhM5Qr71aKVXZ1rlEdlZTXRT_L-KiKcHdNlFvYTyjsPpJy_ApMb_RVj_uxvtDckHEuL2ZGgpqZtPwLr0aQ4AxhgzF2FI4UpcM7wi/s640/minfied.jpg" /></a></div>
<p style="text-align: center; font-size: 0.9em; color: #999; font-style: italic;">Your minified code is just a click away. Note the tabs at the top-right of your code.</p>
<p>
Source maps have been around for some time now. However, I didn't want to implement source maps just so Errorception could wear it as a badge — I wanted to make it actually useful to you. The previous release was a step in this direction — putting your code front and center, and pointing out exactly where the error was in your deployed code. Now, source-maps completes this by not only pointing out exactly the token that caused the error, but also by doing so in your original unminified source file.
</p>
<p>Oh, and of course, this also means that Errorception now supports compile-to-JS languages as well. <a href="http://coffeescript.org/#source-maps">CoffeeScript</a>, <a href="http://typescript.codeplex.com/SourceControl/latest#src/compiler/sourceMapping.ts">TypeScript</a>, <a href="https://github.com/clojure/clojurescript/wiki/Source-maps">ClojureScript</a> and <a href="https://github.com/jashkenas/coffeescript/wiki/List-of-languages-that-compile-to-JS">others</a>, welcome to Errorception! You should feel at home.
<p>As always, suggestions and feedback always welcome. <a href="mailto:rakeshpai@errorception.com">Mail</a>, <a href="https://twitter.com/errorception">Tweet</a>, or leave a comment below.</p>Rakesh Paihttp://www.blogger.com/profile/05275465816567723588noreply@blogger.com2tag:blogger.com,1999:blog-8179719408804246785.post-63540604575288995742014-06-19T11:02:00.002+05:302014-06-19T17:18:54.799+05:30Here's Your Error!<div dir="ltr" style="text-align: left;" trbidi="on">
<p>
Today's release is a game changer!
</p>
<p>
Now, whenever possible, your code and stack-traces take center stage in your error reports. Errorception looks at your code and the data from the error, and attempts to point out where exactly in your source file the error occurred.
</p>
<p>
Although the logic that points out your errors only gets incomplete data to work with, the predictions it makes about the error's cause are stunningly accurate in most cases. Not only does it point out the exact line and column number of the error, it also tries to make sense of your code to find the exact keyword or token that caused the error. And it does this across all stack frames!
</p>
<div class="separator" style="clear: both; text-align: center; margin-bottom: 20px;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUzM3C8OZM18Zti4CeRdnj2fzfKDAphZPVY2q2bOlhGu0_sh0iM34i587hzBbPFlob33lvHM_ozbJxdeJS1A-73cxfcxAintJXVps0MmxocC3BoQcQNt1xukUHmPHEHw6f6iW9-UAYjmNW/s1600/ajax-error-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUzM3C8OZM18Zti4CeRdnj2fzfKDAphZPVY2q2bOlhGu0_sh0iM34i587hzBbPFlob33lvHM_ozbJxdeJS1A-73cxfcxAintJXVps0MmxocC3BoQcQNt1xukUHmPHEHw6f6iW9-UAYjmNW/s640/ajax-error-1.jpg" /></a></div>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh57wQgfBWqwJxXGqrjOx17WZjX68svaVfoQFsozW4fErwngE6Y87tWKPnEqAIFf8ShjzlzJpIR8heC1deg1_reiT9byze-5iyGVgSJ00aYeu7EhNJdzbxR-boFONOxbMkO7ozP06fsN9MW/s1600/ajax-error-2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh57wQgfBWqwJxXGqrjOx17WZjX68svaVfoQFsozW4fErwngE6Y87tWKPnEqAIFf8ShjzlzJpIR8heC1deg1_reiT9byze-5iyGVgSJ00aYeu7EhNJdzbxR-boFONOxbMkO7ozP06fsN9MW/s640/ajax-error-2.jpg" /></a></div>
<p style="text-align: center; font-size: 0.9em; color: #999; font-style: italic;">Two stack frames of an error</p>
<p>See that screaming out: "Here's your error!" Isn't it just amazing how accurate it is? Do you see how easily you will be able to smash bugs with this?</p>
<h2>Browser support</h2>
<p>This feature relies somewhat heavily on stack-traces being available. All recent versions of Chrome (Desktop and Android) provide stack-traces in <code>window.onerror</code> out of the box, so you are already covered there. Stack-traces in <code>window.onerror</code> are new, <a href="http://blog.errorception.com/2013/10/stack-traces-windowonerror-and-future.html">having made it into the spec</a> only recently. <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=355430">Firefox just implemented this</a> about a week ago, so I expect the next release will ship with <code>window.onerror</code> stack traces. This also works for errors from IE10 for at least the first stack-frame, since IE10 provides a column number for every <code>window.onerror</code> error.</p>
<p>Additionally, this works just about everywhere if you <a href="http://blog.errorception.com/2013/01/stack-traces-and-error-objects.html"><code>.push</code> your errors</a> to Errorception. Until recently, Firefox didn't provide column numbers in their stacks, but <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=762556">that just got fixed</a> a couple of days ago, expanding browser support to all popular browsers. In older versions of Firefox, you should still be able to see the highlight for the first stack-frame for <code>.push</code>ed errors.</p>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfby3DdCws_W426F2F8Iw7OfkFNZRGhA0rNZJXlbAodl-0tWh5C48TXAY60l9_zCyEgNc4xIi3WVnIeJy67Jn_XqFjvMZ7vQj2_Gy5Zqy1hfL1Y-uXh-avns47tfgPF_CBLXMguYmfSk-8/s1600/minfied-error.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfby3DdCws_W426F2F8Iw7OfkFNZRGhA0rNZJXlbAodl-0tWh5C48TXAY60l9_zCyEgNc4xIi3WVnIeJy67Jn_XqFjvMZ7vQj2_Gy5Zqy1hfL1Y-uXh-avns47tfgPF_CBLXMguYmfSk-8/s640/minfied-error.jpg" /></a></div>
<p style="text-align: center; font-size: 0.9em; color: #999; font-style: italic;">It even works accurately with minified code!</p>
<p>If it isn't possible to highlight the offending keyword/token, Errorception will attempt to highlight the offending column. Errorception will definitely highlight the line of the error in all cases regardless.</p>
<h2>The tech</h2>
<p>The engineering needed to pull this off has been significant — certainly one of the more complex things I've worked on. At its heart lies a file-store, written from scratch, purpose-built for just this job. A crawler spiders your site for your JS files when errors occur, and saves them in the file-store, which caches and versions your files. This caching and versioning ensures that you see the rightest possible version of the file that caused the error, even if the file might have subsequently changed with new updates. Your files and the history of your error occurrences are then mined to figure out what might have caused the error.</p>
<p>There are no settings to be configured, no knobs to be turned — It All Just Works. Best of all, this is all done without any extra work on the client-side at all, so your users don't face any performance penalty whatsoever.
</p>
<p>This release has been brewing for months, and has been in closed beta for a few weeks now. And today's feature isn't even the main reason I built all of this — it's just an awesome side-effect. But I'll save those details for the next blog post. (Can you spot it?)</p>
<p>As usual, feedback always welcome. <a href="mailto:rakeshpai@errorception.com">Mail</a>, <a href="https://twitter.com/errorception">Tweet</a> or leave a comment below.</p>
</div>Rakesh Paihttp://www.blogger.com/profile/05275465816567723588noreply@blogger.com0tag:blogger.com,1999:blog-8179719408804246785.post-88368996968704112212014-03-25T00:37:00.001+05:302014-03-25T00:37:50.571+05:30Fine-grained control over error posting<p>While Errorception has given you <a href="http://blog.errorception.com/2011/12/control-error-posting-better.html">some control</a> over error posting since a very long time, this has at best been very coarse-grained. Now, that gets fixed.</p>
<p>You now have full programmatic control over which errors get posted to Errorception. You just have to define <code>_errs.allow</code> to be a function that returns <code>true</code> or <code>false</code>. Examples are the best way to demonstrate this, so here goes:</p>
<p>To ignore all errors from say IE6:</p>
<pre><code>_errs.allow = function() {
return (navigator.userAgent.indexOf("MSIE 6") == -1);
}</code></pre>
<p>To only allow errors from yourdomain.com and its subdomains:</p>
<pre><code>_errs.allow = function() {
return (location.hostname.indexOf("yourdomain.com") != -1);
}</code></pre>
<p>You also get the error that's about to be posted as an argument in this function. The error is represented as an object with three properties: the error message, the line number and the script-source URL of the error. So, to ignore all errors that are from ad-script.js.</p>
<pre><code>_errs.allow = function(err) {
return (err.url.indexOf("ad-script.js") != -1);
}</pre></code>
<p>On a side note, this <code>indexOf</code> and <code>-1</code> business above is so ugly! <a href=""><code>String.prototype.contains</code></a> can't come soon enough!</p>
<p>This was a fun feature to build, especially because of a very interesting corner-case. All of this has been well documented, so <a href="https://errorception.com/api/client#allow">give the docs a look</a>. It's very interesting how Errorception uses itself to log errors encountered in this edge-case in a way that doesn't cause the world to implode.</p>Rakesh Paihttp://www.blogger.com/profile/05275465816567723588noreply@blogger.com0tag:blogger.com,1999:blog-8179719408804246785.post-23065785080352025752014-01-13T23:01:00.000+05:302014-01-13T23:01:52.054+05:30Country of Origin<p>
Sometimes, when debugging client-side errors, knowing <em>where</em> the user is from can be useful. For example, I recently had a situation where I had debug an error that only occurred for users behind the <a href="http://en.wikipedia.org/wiki/Golden_Shield_Project">Great Firewall of China</a>. Granted these kinds of issues only crop up rarely, but at such times knowing that this error only occurs in certain geographical locations can be immensely useful when trying to debug.
</p>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBfwSKFCtSOvmB3_jD13tBS8Y7gt406jRofQEuNgstNjo5h_t9-e4mxIk7YOwQZw4X2X0yZodyA5srZN90YvClko5GVaM4FFhtqNPDGKkbzx_P9iwepZsm411bOBvBWKhPhIZT2e2HGLdI/s1600/Screen+Shot+2014-01-13+at+10.32.04+pm.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBfwSKFCtSOvmB3_jD13tBS8Y7gt406jRofQEuNgstNjo5h_t9-e4mxIk7YOwQZw4X2X0yZodyA5srZN90YvClko5GVaM4FFhtqNPDGKkbzx_P9iwepZsm411bOBvBWKhPhIZT2e2HGLdI/s640/Screen+Shot+2014-01-13+at+10.32.04+pm.png" /></a></div>
<p>
Errorception now displays the country of origin of the error occurrence, whenever possible. Due the very nature of IP-address-based geo-location, the location accuracy can only be very coarse-grained, and might even be entirely wrong, but is right most of the time. Also, I only started collecting geo-data over the weekend, so older error occurrences will not have geo data tagged along with it.
</p>
<p>
Happy debugging!
</p>Rakesh Paihttp://www.blogger.com/profile/05275465816567723588noreply@blogger.com3tag:blogger.com,1999:blog-8179719408804246785.post-51169866094030686142013-11-26T20:24:00.000+05:302013-11-26T20:24:36.836+05:30HTTPS Everywhere<p>This has been a long time coming.</p>
<p>Errorception is now proudly 100% HTTPS. (Well, nearly 100% – read on.)</p>
<p>It turns out, migrating a site to HTTPS isn't as simple as it seems, especially if you have to do it right. I had a huge checklist to look at and verify for this launch. Here's what else has changed with this update:</p>
<ul>
<li>Save for this blog and one route that currently needs to be HTTP, all URLs are now strictly only accessible over HTTPS. HTTP access has been disabled. As for that one route and this blog, they are over cookie-less subdomains, and don't carry any sensitive information.</li>
<li>Cookies are only set when using HTTPS, and have been marked as <a href="https://www.owasp.org/index.php/SecureFlag">secure cookies</a>. HTTP cookies that were set in the past are now meaningless. In fact, I've deleted the entire old session-store to ensure that there can be no <a href="http://en.wikipedia.org/wiki/Session_hijacking">session hijacking</a>.</li>
<li>The encryption is end-to-end. In this case, it means that SSL doesn't just terminate at the load-balancer. The connections between the load-balancer and the app servers are also all SSL. <strong>Everything</strong> is encrypted. <a href="http://www.washingtonpost.com/world/national-security/nsa-infiltrates-links-to-yahoo-google-data-centers-worldwide-snowden-documents-say/2013/10/30/e51d661e-4166-11e3-8b74-d89d714ca4dd_story.html">Take that, NSA</a>!</li>
<li>Cookies will henceforth be <a href="https://www.owasp.org/index.php/HttpOnly">inaccessible to client-side code</a> to prevent a large class of XSS attacks.
<li>There are several other security measures implemented. For example, Errorception now implements <a href="http://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security">HTTP Strict Transport Security</a>, <a href="http://en.wikipedia.org/wiki/Clickjacking#X-Frame-Options">prevents clickjacking</a> where possible, reduces <a href="http://msdn.microsoft.com/en-us/library/ie/gg622941(v=vs.85).aspx">MIME-type security risks</a> where possible, and has <a href="http://msdn.microsoft.com/en-us/library/dd565647(v=vs.85).aspx">force-turned on XSS-filters</a> to prevent reflected XSS attacks.</li>
<li>All external assets included in the site are now loaded over HTTPS as well, to prevent <a href="https://developer.mozilla.org/en-US/docs/Security/MixedContent">mixed-content</a> scenarios. All links from communications like emails have been updated to use HTTPS URLs. Links that have been forged in the past will still work, but will be redirected to HTTPS.</li>
</ul>
<p>Unfortunately, because cookies will have to be recreated over HTTPS and since the session store has been cleared to ensure that old cookies are invalid, it means that you will have to log in again to your Errorception account. It's a minor inconvenience, but it's a small price to pay for the vastly improved security.</p>
<p>I'm by no means a security expert, so if you find any lapses, please feel free to let me know. (I'm rakeshpai at errorception dot com.) Also, security is never really <q>done</q>, so I consider this as only the first step in getting to better security.</p>Rakesh Paihttp://www.blogger.com/profile/05275465816567723588noreply@blogger.com1tag:blogger.com,1999:blog-8179719408804246785.post-13405101752863971242013-11-20T19:11:00.001+05:302013-11-20T22:17:23.499+05:30Why Throw When You Can Just Push?<p>
I had <a href="http://blog.errorception.com/2013/01/stack-traces-and-error-objects.html">previously launched</a> a feature to <code>.push</code> your errors to Errorception if you liked. It also required you to <code>throw</code> your errors immediately after the push.
</p>
<p>
Turns out, many people don't like to <code>throw</code> their errors. There could be several reasons for not throwing your errors – for example, if you want to handle it gracefully, but still want it logged. Also, some frameworks such an <a href="http://docs.angularjs.org/api/ng.$exceptionHandler">Angular</a> and <a href="http://ianpetzer.wordpress.com/2013/07/24/dont-let-ember-js-swallow-errors-in-your-promises/">Ember</a> provide you with Error objects, but throwing them might not be what you want to do.
</p>
<p>
Now with Errorception, you don't need to <code>throw</code> error objects anymore. Simply <code>.push</code> them, and you are done!
</p>
<p>
I must hasten to add that I would consider this usage <q>advanced</q>. A <code>throw</code>, despite all its weirdness, is the best way to halt a problem immediately. If there's an error that you haven't anticipated, chances are you will want to stop your program's execution. If you are going to deal with errors properly, you don't need to throw them, but then you wouldn't have an error in the first place. This makes the feature only useful for a small set of cases. If you are not throwing your error, I hope you know what you are doing.
</p>
<p>If your code was already throwing errors after pushing them, you won't have to change a thing. Don't worry – you won't get duplicate errors. In fact, this behaviour (<code>push</code>, with or without <code>throw</code>, without duplicates) will be supported forever, because of the reasons in the paragraph above.</p>Rakesh Paihttp://www.blogger.com/profile/05275465816567723588noreply@blogger.com3tag:blogger.com,1999:blog-8179719408804246785.post-24665895635951313182013-10-22T22:50:00.001+05:302013-10-23T04:51:37.877+05:30Stack Traces, window.onerror, and the future<p>One argument that many people have made (and still make) is that <code>window.onerror</code> doesn't provide sufficient information to track down client-side JavaScript errors. While there's certainly some truth to it, I've always thought of it as a case of <a href="http://en.wikipedia.org/wiki/Worse_is_better">worse is better</a>.</p>
<p>Consider the alternative: you'd have to wrap all your code in try/catch blocks. But that's not enough. Because of the nature of the event loop in browsers, you will also have to wrap all your async code in try/catch blocks as well. That includes all DOM event handlers, XHR and <a href="https://developer.mozilla.org/en/docs/AJAX">family</a> including <a href="https://developer.mozilla.org/en/docs/WebSockets">WebSockets</a>, and <code>setTimeout</code> and <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Timers">family</a>. That's something you'll just have to do. Because this requires modification of your code, it's terribly invasive. This also means that you will almost certainly miss catching errors in several cases, simply due to oversight. And that's still not saying anything about the <a href="https://code.google.com/p/v8/issues/detail?id=1065">performance overhead</a> of working with try/catch blocks, <a href="http://jsperf.com/try-catch-block-performance-comparison">not just in Chrome</a>. All that, just to get some additional data.</p>
<p>Errorception lets you <a href="http://blog.errorception.com/2013/01/stack-traces-and-error-objects.html">pass your error objects to us</a> if you want to, since quite some time now. However, less than 10% of errors at Errorception are recorded using this method. It is obvious that the <code>window.onerror</code> approach works far better, either because try/catch isn't comprehensive, or because it is inconvenient to use.</p>
<h3><pre style="background: #eee; padding: 3px; border: 1px solid #bbb; font-weight: normal;"><code>window.onerror = function(message, fileName, lineno) { ... }</code></pre></h3>
<p>That's all the data you got from <code>window.onerror</code>: the error message, the URL of the script, and the line number. Errorception of course records much more information about the browser and its state for you automatically, so there's already a lot of context available.</p>
<p>But Errorception has sorely lacked a very vital piece of data to aid debugging: stack traces. Stack traces are trivial to extract from the error object you get in the <code>catch</code> block of a <code>try/catch</code> statement. Sure, there were a couple of <a href="http://blog.errorception.com/2011/12/call-stacks-in-ie.html">tricks up our sleeve</a> to get fake stack traces where possible, but those were severely limited.</p>
<p>Obviously this problem wasn't one that just Errorception faced. The web community went to browser vendors and standards bodies with their torches and pitchforks (ok, it wasn't quite as dramatic as that), to ask for some love for <code>window.onerror</code>. A couple of months ago, the HTML spec finally <a href="http://html5.org/tools/web-apps-tracker?from=8085&to=8086">added</a> two <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#errorevent">new attributes for <code>window.onerror</code></a>.</p>
<h3><pre style="background: #eee; padding: 3px; border: 1px solid #bbb; font-weight: normal;"><code>window.onerror = function(message, fileName, lineno, <strong>colno, error</strong>) { ... }</code></pre></h3>
<p>See that last argument there? That's what's exciting. That's the error object you would have otherwise got if you had wrapped your code in try/catch blocks. That's right: You don't need to wrap your code in try/catch blocks anymore to get rich error information. This changes everything!</p>
<h2>Browser support</h2>
<p>As of this writing, no production browser supports these new attributes. But don't let that dishearten you – the spec is only about 3 months old after all. IE10 does support the <code>colno</code> attribute, but not the error object itself. That's because IE10's release predates the spec. I expect the next release of IE to have the error object supported. (Seriously, let's cut IE some slack. They've been doing some rocking work lately. They certainly took the lead here.) Chrome already <a href="https://code.google.com/p/chromium/issues/detail?id=147127">rolled this out in Chrome Canary</a> two months ago, so it should be be in a public release soon. <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=355430">Discussions are on in Firefox's Bugzilla</a>, and I expect this to be resolved soon as well. The folk over at <a href="https://bugs.webkit.org/show_bug.cgi?id=55092">WebKit seem interested too</a>, though admittedly progress has been slow.</p>
<h2>Errorception and window.onerror</h2>
<p>Needless to say, Errorception has now rolled out support for the new attributes on <code>window.onerror</code>. Since Errorception already uses <code>window.onerror</code> to record errors, you literally don't need to change a thing (yes, even though the attributes are <q>new</q>). Errorception will record stack traces for your errors whenever available. In fact, I've already tested this with Chrome Canary, and it works like a charm! Yes, this <a href="http://blog.errorception.com/2012/12/catching-cross-domain-js-errors.html">works for Cross-Origin errors too</a>!</p>
<p>This should finally lay to rest the argument about whether try/catch blocks are better for JavaScript error logging, or if one should use <code>window.onerror</code> instead. There's absolutely no advantage to using try/catch blocks for error logging anymore. It's still useful for handling exceptions, sure, but it isn't useful for logging. And if you are using Errorception, you are already using the best mechanism for error logging. Of course, you should be used to that by now. ;)</p>
<p>As always, if you have any questions or feedback, the comments are open.</p>Rakesh Paihttp://www.blogger.com/profile/05275465816567723588noreply@blogger.com0tag:blogger.com,1999:blog-8179719408804246785.post-87532995964061329812013-10-14T23:31:00.001+05:302013-10-14T23:31:24.886+05:30Say Hello To CORS<p>Errorception now uses <a href="http://en.wikipedia.org/wiki/Cross-origin_resource_sharing">CORS</a> when available to send errors from the browser to the server. This makes the error POSTing process much more lightweight.</p>
<p>This wasn't the case so far. Error information was encoded into form fields and posted into a hidden iframe. While this largely worked fine, it wasn't without its problems. Serialising data as form fields isn't a big deal, even if slightly wordy. However, iframes are very resource-heavy, and are fraught with performance problems. Also, iframes are essentially just regular page loads, so they fire up the browser's loading indicators in the browser tab and show that little message in the status bar of the browser. All of this happens simultaneously. Obviously, users don't like this.</p>
<p>However, two years ago when Errorception was launched, JSON and CORS wasn't as ubiquitous as it is today. Forms and iframes, despite their problems, were the only workable solution, especially if like me you insist on using POST for posting data. Fast-forward to today, and the world is a different place. <a href="http://caniuse.com/json">JSON</a> and <a href="http://caniuse.com/cors">CORS</a> are available in every browser worth their salt.</p>
<p>After weeks of development and extensive testing, I've released a new version of the tracking code to make use of JSON and CORS where possible, to ensure that your users see the least amount of performance degradation at any time. If CORS (or Microsoft's <code>XDomainRequest</code>) isn't available, the code falls back to working as it always has - with form fields and iframes.</p>
<p><strong>Upgrade if you haven't already!</strong> This new code is only released to people who are using the latest tracking snippet. The new tracking snippet was <a href="http://blog.errorception.com/2013/05/better-script-delivery.html">released earlier this year</a>, and already implements tons of performance improvements over the old one. You should upgrade if you haven't already. If you signed up after May, you are already on the latest code. If you've upgraded already, you rock!</p>Rakesh Paihttp://www.blogger.com/profile/05275465816567723588noreply@blogger.com0tag:blogger.com,1999:blog-8179719408804246785.post-79543266679044378672013-07-02T19:33:00.000+05:302013-07-02T19:33:50.023+05:30IE's i18n Strings for Error Messages<p>After <a href="http://blog.errorception.com/2013/06/all-your-errors-now-in-english.html">the release last week</a>, there have been some requests to both Raj and me to have access to the raw data used for powering the IE i18n de-duplication, from several people, including from some of my competitors.</p>
<p>After a little bit of email back-and-forth with Raj, and ensuring that we were both ok with making this data available publicly, I'm glad to to have just pushed <a href="https://github.com/errorception/ie-error-languages">all the raw data to GitHub</a>. Go ahead, give it a look!</p>
<h2>What? You are giving data to your competitors?</h2>
<p>Well, firstly, it isn't my data at all. It wasn't even extracted by me. Secondly, this isn't the kind of stuff I want to compete on. Data like this should ideally belong to everyone, so that the entire community benefits from it. This data being locked into any one service is doing disservice to the community at large. In fact, when I started this conversation with Raj, my original intention was to get MicroSoft to publish these resource files publicly so that everyone could benefit from it.</p>
<p>Cheers!</p>Rakesh Paihttp://www.blogger.com/profile/05275465816567723588noreply@blogger.com2tag:blogger.com,1999:blog-8179719408804246785.post-10569174691707518802013-06-25T17:28:00.000+05:302013-06-25T17:28:29.886+05:30All Your Errors, Now In English<p>Internet Explorer has this interesting behavior that all its errors are localized to the user's preferred language. I'm not sure if that's a good thing, since <a href="http://www.codinghorror.com/blog/2009/03/the-ugly-american-programmer.html">English is effectively the lingua-franca of programming</a>, and there are so few <a href="http://en.wikipedia.org/wiki/Non-English-based_programming_languages">programming languages that don't use English keywords</a>. Ah, well. One could argue, that if the user has set their browser locale to a non-English language, the browser should display errors in the user's preferred language. After all, the error message is seen by the user.</p>
<p>However, with Errorception, errors are taken out from the browser and saved on a server for an entirely different audience to see. The fact that the language isn't English causes all sorts of problems. Since the languages are different, it's hard to tell at a glance if two errors are duplicates of each other. As you will have multiple error entries created because of this, it leads to other problems. For example, you can't prioritize correctly, since the number of errors are more than they should be, and number of individual occurrences of these errors are less than they should be. It's such a mess!</p>
<p>I'm proud to announce that this problem has now been cracked in the most comprehensive and cleanest way possible. With a lot of help from <a href="https://twitter.com/avranju">Rajasekharan Vengalil</a>, Developer Evangelist at Microsoft, we managed to extract the language resource bundles from Internet Explorer's binaries for 35(!) different languages. (By "with a lot of help", I mean "he did all the work".) Once I had the language files, I could then create a mapping between errors in different languages.</p>
<p>Now, when an error comes to Errorception, the code walks across the language mapping, figures out the language of the error and its corresponding English version, finds the tokens (variable names, generally) in the error message, puts these tokens into the appropriate places in the English version of the error, and thus reconstructs the English version of the error. For completeness, the original error is also stored along with your <a href="http://blog.errorception.com/2012/11/raw-error-data.html">raw logs</a>.</p>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1lYtMtWXnpBpc4Or4V1ycfWUE9HwXLAMpYe14vReMv5MtMRVgONSoc2PHcgNHHB_icPQODvH-w2wgbOf-_aptEcE6wzR1NmQmt_0zUQF-rklHQBPVI1XYXxFasX9FN-xB36EV0ZUr1xUK/s1600/russian-to-english.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1lYtMtWXnpBpc4Or4V1ycfWUE9HwXLAMpYe14vReMv5MtMRVgONSoc2PHcgNHHB_icPQODvH-w2wgbOf-_aptEcE6wzR1NmQmt_0zUQF-rklHQBPVI1XYXxFasX9FN-xB36EV0ZUr1xUK/s640/russian-to-english.png" /></a></div>
<p>So, starting some time ago, you will now receive all your errors in English, even if the errors are in browsers with a different language! This also means that the right error messages from IE are grouped together correctly, irrespective of the users' settings! And this works across 35 languages for hundreds of errors – even the latest bunch of errors thrown with the new ES5 support in IE!</p>
<p>Oh, and don't forget to buy Raj a beer when you meet him. :)<p>Rakesh Paihttp://www.blogger.com/profile/05275465816567723588noreply@blogger.com3tag:blogger.com,1999:blog-8179719408804246785.post-29132888387104568232013-05-20T11:20:00.000+05:302013-05-20T11:20:34.098+05:30Better Script Delivery<p>I'm in the process of switching CDNs from Amazon's CloudFront to CloudFlare. While CloudFront has been generally good, it fell short in a couple of ways. So far, CloudFlare solves all of these problems and then gives the opportunity to have even more interesting possibilities.<p>
<p>There were two major problems with CloudFront:</p>
<ul><li><strong>No CNAME support</strong>. Not for HTTPS, at least. As a result, I've had to give you a script with a <code>someuglytoken.cloudfront.net</code> URL in it. But the problem is beyond just ugliness. It gives me no control to change CDNs in the future. I've been living with this so far, but it's far from ideal. CloudFlare solves this problem elegantly.</li>
<li><strong>It's a dumb CDN</strong>. Like, really dumb. It doesn't do any content-negotiation for what I'd consider even the most basic things. For example, if you want your scripts to be gzipped, you'd have to upload pre-gizpped scripts to the CloudFront. If a browser comes along that doesn't understand gzip, it's out of luck.</li>
</ul>
<p>The second issue might seem obvious and trivial, but has its consequences. For example, PageSpeed recommends that every asset on the page should have a <code>Vary: Accept-Encoding</code> header. However, on CloudFront if I provide a <code>Vary</code> header, I'd be lying to the network, because I'm not able to vary the content at all. As a result, all sites that had embedded Errorception's snippet would have seen a slight reduction in their PageSpeed score. Indeed, <a href="https://errorception.uservoice.com/forums/132896-suggestions-and-feedback/suggestions/3863028-specify-a-vary-accept-encoding-header-for-pagespe">there have been requests to fix this</a>.</p>
<p>Not only do the two problems above get fixed by the move to CloudFlare, it allows for very interesting possibilites in the future. Since CloudFlare is much more smart as compared to CloudFront, and since it effectively works as a caching-proxy, the possibilities are limitless! There are features I simply couldn't roll out on CloudFront which become trivial to do on CloudFlare.</p>
<h3>Action needed</h3>
<p>Unfortunately, this change requires you to change the script snippet that you've embedded on your site. I know it's a pain to have to do this. I apologize. The <a href="http://blog.errorception.com/2012/01/now-using-cdn-power.html">last time</a> I asked you to do this was over a year and a half ago, so I assure you that these kinds of changes don't happen frequently. Please go to your Settings > Tracking snippet to get the new snippet.<p>
<h2>Upgrade plan</h2>
<p>The current script on Amazon's CloudFront will be supported for a couple of months more. Over this period, if there are any critical bugs, I'll be making releases to both the CloudFront and CloudFlare CDNs. Feature releases will <strong>not</strong> be rolled out to CloudFront, so you will not get any new features if you are using the old snippet. It's highly recommended that you upgrade as soon as possible to ensure that you have the very latest features.</p>Rakesh Paihttp://www.blogger.com/profile/05275465816567723588noreply@blogger.com1tag:blogger.com,1999:blog-8179719408804246785.post-39357576846547548502013-04-29T19:33:00.000+05:302013-04-29T19:47:48.208+05:30Get your JS error notifications wherever you like!<p>Just three days ago, I had launched <a href="http://blog.errorception.com/2013/04/announcing-webhooks.html">WebHooks support</a> so that you can view your site's client-side JS errors anywhere you prefer. The trouble with vanilla WebHooks is that everyone has to implement the same sets of hooks for integration with the same services. For example, if two companies need the error to be posted to HipChat, they'd both have to independently develop HipChat integrations on top of Errorception's WebHooks, and then manage and maintain their implementations themselves. Such a pain! So, today, there are two announcements to help ease the pain.</p>
<p>Firstly, using the same underlying stack I'm using for WebHooks, I'll host integrations for most popular services myself so that you don't have do a thing. I'm calling this <q>service hooks</q>, blatantly copying the name from GitHub. Simply go over to your settings, and click on <q>Service Hooks</q> to find the list of services you can already integrate with today. You don't have to write any code to implement the hook. Just fill a form, and you are ready to go.</p>
<p>Currently, I'm launching <a href="http://campfirenow.com/">Campfire</a>, <a href="https://www.hipchat.com/">HipChat</a> and <a href="http://www.pagerduty.com/">PagerDuty</a> integration. Integrations with these services have been asked for before, so I decided to start with these. I expect this list to expand further.</p>
<div style="text-align: center">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpOO1q86UyVX56ac4XohQJxS8LEHsnLZdK0aKERsHgfU-cYqX1eBBlQHoLDo7OIz9mjCYKZWY0_MljSWImLEkAQXBXYxcCqPK55OVTJGSjmOGOzXbmFIzSQ-o5xONqtCThzxnbljB1uySv/s1600/Screen+Shot+2013-04-29+at+6.02.44+PM.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpOO1q86UyVX56ac4XohQJxS8LEHsnLZdK0aKERsHgfU-cYqX1eBBlQHoLDo7OIz9mjCYKZWY0_MljSWImLEkAQXBXYxcCqPK55OVTJGSjmOGOzXbmFIzSQ-o5xONqtCThzxnbljB1uySv/s320/Screen+Shot+2013-04-29+at+6.02.44+PM.png" /></a> <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKh8rkHExZYHoiNEs12LyG-YnVfe6j4qK-V9LbtSDDUtW8ITujpEctCtG8z8ZUDTtlXj1AsbE76PgSiUqOI7OPXYp7V_eVU3HqpX2FoVOesTcGx5TDDGzLC6ZEa3c5CBqeV6_2JNd4vGp0/s1600/Screen+Shot+2013-04-29+at+6.17.15+PM.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKh8rkHExZYHoiNEs12LyG-YnVfe6j4qK-V9LbtSDDUtW8ITujpEctCtG8z8ZUDTtlXj1AsbE76PgSiUqOI7OPXYp7V_eVU3HqpX2FoVOesTcGx5TDDGzLC6ZEa3c5CBqeV6_2JNd4vGp0/s320/Screen+Shot+2013-04-29+at+6.17.15+PM.png" /></a>
<p style="color: #999; font-size: 11px">What an error looks like on Campfire (left) and HipChat</p>
</div>
<p>As interesting as that is, what's even more exciting is how it's implemented, and how it matters to you.</p>
<h2><3 GitHub, <3 open-source</h2>
<p>All the code that makes these service hooks possible is all open-source. <a href="https://github.com/errorception/errorception-hooks">Check it out on GitHub</a>. Even the documentation on Errorception for these services is driven off README.md files from GitHub! That's just awesome!</p>
<p>There are two reasons I wanted this to be open-source. One of the reasons of course is that I like the transparency with open source. When I'm asking you to enter API tokens for, say, your HipChat account, I want to make it clear to you that I'm not going to misuse it. What better way to convince you than to show you the code itself!</p>
<p>Secondly, and probably more importantly, if you want to see a new service integrated with Errorception, you will be able to do that yourself! Just fork the repo on GitHub, write a small little JS function to implement the integration, and send me a pull request. I'll have it merged in no time, and will immediately be available to everyone. It's really simple! And when I say it's a <q>small little function</q>, I mean it - Have a look at <a href="https://github.com/errorception/errorception-hooks/blob/master/hooks/webhook/index.js#L13-L25">the WebHooks implementation</a> as an example.</p>
<p>I've had a lot of fun planning and coding this release. I hope you make the most of it. And if you want to see your favorite services integrated with Errorception, feel free to give it a shot on GitHub. I'll only be glad to help you along.</p>Rakesh Paihttp://www.blogger.com/profile/05275465816567723588noreply@blogger.com4tag:blogger.com,1999:blog-8179719408804246785.post-21358272124742582142013-04-26T22:14:00.000+05:302013-04-26T22:14:05.158+05:30Announcing WebHooks<p>Though the Errorception <a href="http://errorception.com/api/http">HTTP API</a> is awesome for browsing your errors, it has so far been very hard to get real-time error notifications. There was the hacky solution of polling the API of course, but that's terribly inefficient, and just feels dirty. Today, this gets fixed.</p>
<p>You can now configure WebHooks in your settings, which Errorception will POST to whenever it encounters an error on your site. You can choose if you want to receive POSTs for every occurrence of every error, of the very first time an error occurs.<p>
<div style="text-align: center">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgW7-5K1_n9yYj441VRU372-RukpQaxIYQa-p_2bABB_UA8PjKSfZcUQrpwhAtiUhSAtZXMS6aElWO7diCJlIDxRvQyeEcORqE3iPjLs5L4zOBwqWlPRXckNvVvKFkOqhEdiTuZFxudsG0S/s1600/Screen+Shot+2013-04-26+at+10.01.18+PM.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgW7-5K1_n9yYj441VRU372-RukpQaxIYQa-p_2bABB_UA8PjKSfZcUQrpwhAtiUhSAtZXMS6aElWO7diCJlIDxRvQyeEcORqE3iPjLs5L4zOBwqWlPRXckNvVvKFkOqhEdiTuZFxudsG0S/s700/Screen+Shot+2013-04-26+at+10.01.18+PM.png" /></a></div>
<p>This has been made available to all projects in Errorception, just like every other feature. Head over to the <a href="http://errorception.com/api/webhook">WebHook docs</a> to learn how to make the most of this feature.<p>
<p>As usual, feedback always welcome! I can't wait to see what you'll be pulling off with this. :)</p>Rakesh Paihttp://www.blogger.com/profile/05275465816567723588noreply@blogger.com2tag:blogger.com,1999:blog-8179719408804246785.post-31371847095829206892013-02-19T17:22:00.000+05:302013-02-19T18:16:32.369+05:30Error Object Compatibility Table<p>I've been spending some time lately studying JavaScript's Error object. These are some of my notes on Error object compatibility across browsers, in case anyone else finds this useful.</p>
<style>
.compatTable td { text-align: center; }
.compatTable .separate th, .compatTable .separate td { border-top: 1px solid #eee; }
</style>
<table width="100%" class="compatTable">
<thead>
<tr>
<th>Property</th>
<th>Google Chrome</th>
<th>Safari</th>
<th>Opera</th>
<th>Firefox</th>
<th>MSIE</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row" align="left">name</th>
<td>Yes</td>
<td>Yes</td>
<td>Yes</td>
<td>Yes</td>
<td>Yes</td>
</tr>
<tr>
<th scope="row" align="left">message</th>
<td>Yes</td>
<td>Yes</td>
<td>Yes</td>
<td>Yes</td>
<td>Yes</td>
</tr>
<tr>
<th scope="row" align="left">stack</th>
<td>Yes</td>
<td>Yes</td>
<td>Yes</td>
<td>Yes</td>
<td>Yes (IE10+)</td>
</tr>
<tr>
<th scope="row" align="left">toString()</th>
<td>Yes</td>
<td>Yes</td>
<td>Yes</td>
<td>Yes</td>
<td>Yes</td>
</tr>
<tr class="separate">
<th scope="row" align="left">type</th>
<td>Yes</td>
<td>No</td>
<td>No</td>
<td>No</td>
<td>No</td>
</tr>
<tr>
<th scope="row" align="left">columnNumber</th>
<td>No</td>
<td>No</td>
<td>No</td>
<td>Yes</td>
<td>No</td>
</tr>
<tr class="separate">
<th scope="row" align="left">fileName</th>
<td>No</td>
<td>No</td>
<td>No</td>
<td>Yes</td>
<td>No</td>
</tr>
<tr>
<th scope="row" align="left">sourceURL</th>
<td>No</td>
<td>Yes</td>
<td>No</td>
<td>No</td>
<td>No</td>
</tr>
<tr class="separate">
<th scope="row" align="left">line</th>
<td>No</td>
<td>Yes</td>
<td>No</td>
<td>No</td>
<td>No</td>
</tr>
<tr>
<th scope="row" align="left">lineNumber</th>
<td>No</td>
<td>No</td>
<td>No</td>
<td>Yes</td>
<td>No</td>
</tr>
<tr class="separate">
<th scope="row" align="left">number</th>
<td>No</td>
<td>No</td>
<td>No</td>
<td>No</td>
<td>Yes</td>
</tr>
</tbody>
</table>
<br />
<h2>Notes:</h2>
<ul>
<li>Though file name is available in the <code>.stack</code> property, only Firefox and Safari provide this as an explicit property, and that too with different property names (FF: <code>.fileName</code>, Safari: <code>.sourceURL</code>).</li>
<li>All browsers string-format the stack subtly differently. There's no standard regarding stack formatting. Firefox has the least informative stack property. I'm going to cut Firefox some slack though, since they were the first to expose this property. That said, this might change in the future. Worth keeping an eye on <a href="http://wiki.ecmascript.org/doku.php?id=strawman:error_stack">this discussion</a>.</li>
<li>Firefox doesn't provide column numbers in the stack at all. However, it does provide a <code>.columnNumber</code> property which is only useful for the first stack frame.</li>
<li>The <code>.number</code> property (IE) is practically useless. It points to IE's internal representation of errors.</li>
<li><code>.line</code> (Safari) and <code>.lineNumber</code> (Firefox) properties give the line number of the first stack frame of the error. No one else provides a similar property, though this data is available in the <code>.stack</code> everywhere except Firefox.</li>
<li>The <code>.toString()</code> formatting seems consistent, and similar to the formatting of the error message in <code>window.onerror</code>. That is, it uses the format <code>name + ": " + message</code>. The only exception to this, of course, is that <code>window.onerror</code> formats errors differently <a href="http://blog.errorception.com/2012/04/script-error-on-line-0.html">when the source file has x-domain restrictions</a>.</li>
<li>Column numbers in the <code>.stack</code> property are only available in IE10+ and Chrome. Opera provides a <code>.stacktrace</code> property in addition to <code>.stack</code> that has column numbers (go figure!). No other browser provides column numbers in the stack trace. As mentioned above, Firefox does provide an explicit <code>.columnNumber</code> property that's only useful for the first stack frame.</li>
<li>No stack support for IE<10. Nothing. Zilch.</li>
</ul>Rakesh Paihttp://www.blogger.com/profile/05275465816567723588noreply@blogger.com0tag:blogger.com,1999:blog-8179719408804246785.post-75517698859825094892013-01-31T00:44:00.000+05:302013-11-20T19:13:12.112+05:30Stack Traces and Error Objects<p>A frequently requested feature has been that of stack traces with errors. However, because <code>window.onerror</code>, doesn't give access to an error object, it has not been possible for Errorception to capture stack traces. That's set to change today.</p>
<p>Starting today, you will be able to pass error objects to Errorception. An example is probably the best way to explain this.</p>
<pre style="background: #f9f9f9; padding: 10px;"><code>try {
var myObject = JSON.parse(jsonString); // will break if jsonString is invalid
} catch(e) {
<strong>_errs.push(e);</strong>
<strong>throw e;</strong>
}
</code></pre>
<p>When you pass such errors manually to Errorception, Errorception will now be able to record the stack trace for this error. Undoubtedly, this can be very useful for debugging.</p>
<h2>Important</h2>
<ul>
<li>What you <code>push</code> to <code>_errs</code> should be a valid Error object, that is, it should be an <code>instanceof Error</code>.</li>
<li>It is important that you <code>throw</code> the error right after passing it to <code>_errs</code>. This is for two reasons. Firstly, you really want your program's execution to stop when you encounter an error, and <code>throw</code> is a great way to do so. <strike>Secondly, Errorception internally uses both the <code>Error</code> object and the data from <code>window.onerror</code> to capture error data. If you don't <code>throw</code> the error, Errorception will ignore the error object.</strike> <strong>Update</strong>: Throwing errors <a href="http://blog.errorception.com/2013/11/why-throw-when-you-can-just-push.html">isn't required</a> anymore, but is highly recommended.</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqK_TkisrQqMc4C8vUJEhW3hVb6h5A940mmitm4qcb4ZfzShagxXU1xguETIj_e1hTgB7I3xIAUnAb_60DTmiUQ5wNh68mnToLdCQF0HQeDdM2zUeVWXzHpzTlqCK1xrVYrgt8UZM5y3_v/s1600/Call+stack.png" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" width="700" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqK_TkisrQqMc4C8vUJEhW3hVb6h5A940mmitm4qcb4ZfzShagxXU1xguETIj_e1hTgB7I3xIAUnAb_60DTmiUQ5wNh68mnToLdCQF0HQeDdM2zUeVWXzHpzTlqCK1xrVYrgt8UZM5y3_v/s700/Call+stack.png" /></a></div>
<p>As an additional bonus, with the exception of Firefox and Safari, you will also get the column number of your error. This is especially important since your JS is likely minified without line-breaks. This column number information is especially exciting — it's likely to guide the future features of Errorception.</p>
<p><strong>Bonus</strong>: This works perfectly well with the recently launched ability to <a href="http://blog.errorception.com/2012/11/capture-custom-data-with-your-errors.html">record custom information with errors</a>. For example, in Errorception I was recently doing this (yes, Errorception uses Errorception):</p>
<pre style="background: #f9f9f9; padding: 10px;"><code>try {
var myObject = JSON.parse(jsonString);
} catch(e) {
<strong>_errs.meta = {json: jsonString};</strong>
_errs.push(e);
throw e;
}
</code></pre>Rakesh Paihttp://www.blogger.com/profile/05275465816567723588noreply@blogger.com10tag:blogger.com,1999:blog-8179719408804246785.post-89014281998533592762013-01-11T06:31:00.000+05:302013-01-11T06:31:23.902+05:30Your JS Errors Are Now An API Call Away<p>It always annoys me when data gets caught in inaccessible silos, yet that's exactly what I had ended up building with Errorception. Today, that gets rectified.</p>
<p>Today I'm announcing the first cut of the Errorception API. As far as I know at least, it is the first API in the wild tailored specifically for JS errors in your site.</p>
<p>Being a huge fan of simplicity, the API is really simple to use too. In fact, I've embedded a <code>curl</code> example right here in this blog post:</p>
<pre style="background: #444; font: 13px Monaco, 'Courier New', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; color: #eee; padding: 10px;"><code>$ curl -i https://api.errorception.com/
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 77
Connection: keep-alive
{"links":[{"rel":"projects","href":"https://api.errorception.com/projects"}]}
</code></pre>
<p>You can view detailed API documentation on <a href="http://errorception.com/api/http">the API docs page</a>.</p>
<p>I'm excited to see what you will do with this data. I'm hoping to evolve this API based on what your experience is like. As usual, feel free to mail me at rakeshpai at errorception dot com with any suggestions or feedback.</p>Rakesh Paihttp://www.blogger.com/profile/05275465816567723588noreply@blogger.com2tag:blogger.com,1999:blog-8179719408804246785.post-27316857254395788952013-01-06T11:10:00.001+05:302013-01-06T11:12:18.894+05:30Improving Daily Emails<p>The daily notification email, which had been turned off for some time now due to a snag, has now been turned back on.</p>
<p>Previously, all the emails used to be sent at the turn of the day on the server. This was problematic in at least two ways.</p>
<ul><li>The load on the DB to sift through the large volume of errors to generate emails was turning out to be a bit much. The server had begun to protest about the load.</li><li>All users got emails at the same time, irrespective of which timezone they belonged to. I would personally prefer to get my error notification in the morning when I'm starting my day, so that I can schedule time for fixing it. A mail that lands up in my mailbox when I'm about to go to bed is useless at best, and worrisome at worst.</li></ul>
<p>Turns out, solving the latter problem solved the former problem as well, because the server load of sending out the email would get more-or-less evenly distributed across the entire day. So, taking inspiration from <a href="https://strideapp.com/blog/2012/11/sending-morning-emails/">what Stride did recently</a>, I've rolled out something similar for Errorception.</p>
<p>A <a href="https://bitbucket.org/pellepim/jstimezonedetect">small JS snippet</a> notes your timezone every time you use Errorception. This timezone information is passed along to the server and recorded against your records. A cron kicks in every half hour on the server to determine if you should be sent an email to right now, based on whether it is 9:30 AM in your timezone, using the excellent <a href="https://github.com/TooTallNate/node-time">'time' module by Nathan Rajlich (TooTallNate)</a>. It just works!</p>
<p>So, starting about 15 mins ago, you should now receive emails at 9:30 in the morning, irrespective of which timezone you are in, or whether it's daylight savings or not. If you still aren't receiving emails, get in touch at rakeshpai at errorception dot com.</p>
<p><strong>Almost forgot:</strong> Wish you a great 2013! Happy debugging!</p>Rakesh Paihttp://www.blogger.com/profile/05275465816567723588noreply@blogger.com0tag:blogger.com,1999:blog-8179719408804246785.post-68852652304936542672012-12-14T22:18:00.000+05:302013-01-19T12:38:06.411+05:30Catching Cross-Domain JS Errors<p>
As I've <a href="http://blog.errorception.com/2012/04/script-error-on-line-0.html">mentioned before</a>, most modern browsers do not provide access to error information in <code>window.onerror</code> for scripts loaded from across domains. This is a very severe restriction, and has limited the usefulness of <a href="http://errorception.com/">Errorception</a> to some extent.
</p>
<p>
Fortunately, a couple of months ago, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=696301">Firefox landed a patch</a> to add this feature, and this has already been shipped with the latest versions of Firefox. Chrome is expected to follow suit very soon, since this has already <a href="https://bugs.webkit.org/show_bug.cgi?id=81438">landed in Webkit</a>.
</p>
<p>
Unfortunately, this doesn't work out of the box, and will require some tweaking of your server and markup. Fortunately, the changes you need to make are minimal.
</p>
<h2>On the server</h2>
<p>You will need to <a href="http://enable-cors.org/">enable CORS</a> for the external JS file you load. The most minimal way to do this is to set the following HTTP header in the response for your JS file.
</p>
<p><code>Access-Control-Allow-Origin: *</code></p>
<p>That's the only server-side change you need to make!</p>
<h2>In the markup</h2>
<p>Script tags have now got a new non-standard attribute called <code>crossorigin</code>. The most secure value for this would be <code>anonymous</code>. So, you'll have to modify your script tags to look like the following.</p>
<p><code><script src="http://sub.domain.com/script.js" <b>crossorigin="anonymous"</b>></script></code></p>
<h2>Browser support</h2>
<p>As of this writing, only Firefox <a href="https://developer.mozilla.org/en-US/docs/HTML/Element/script#attr-crossorigin">supports</a> reporting errors for cross-domain scripts. All WebKit browsers including Chrome is expected to support this very soon. This isn't a problem with IE at all, since IE already reports errors to <code>window.onerror</code> irrespective of the domain (yay, security!). Standardisation for the new attribute <a href="http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2012-February/034969.html">has been proposed</a> though it hasn't gotten anywhere.</p>
<p><strong>Update</strong>: Thanks to Matthew Schulkind for pointing out <a href="http://blog.errorception.com/2012/12/catching-cross-domain-js-errors.html?showComment=1358574712626#c9011348141614317852">in the comments below</a>: It appears that Firefox insists that if you are using the cross-origin attribute, the script file must be served with the access control HTTP header. If the access control header isn't present, the script simply doesn't get evaluated. This is a minor annoyance at development time, so I've <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=832587">filed a bug with Mozilla</a> about this.Rakesh Paihttp://www.blogger.com/profile/05275465816567723588noreply@blogger.com19tag:blogger.com,1999:blog-8179719408804246785.post-86262729238309429762012-11-23T18:08:00.000+05:302013-02-20T03:43:58.680+05:30Capture Custom Data With Your Errors<p>The more context you have around an error, the better it'll help you when debugging. And who understands your application's context better than you!</p>
<p>Starting today, you will be able to record custom information with your errors. It's super simple too! Just create an <code>_errs.meta</code> object, and add anything you want to it!</p>
<script src="https://gist.github.com/rakeshpai/4135253.js"></script>
<p>You can pass the <code>_errs.meta</code> object any number of properties, and the values can either be strings, numbers or booleans. Values with other types will be ignored.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJNvlUWmBZ1_MjBqn_cn6PvtPijBQJ-7PwT_knPpFDeNvjpzMG1v_l1ECUmtVZFdQdtLMpuQpY7Pz2KG_W4mw08C8bRhwc8LZK17feimVYGNKPMODBo_NBDk9kWJZMnpu1CiqVZP9sActj/s1600/custom-data.png" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" width="681" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJNvlUWmBZ1_MjBqn_cn6PvtPijBQJ-7PwT_knPpFDeNvjpzMG1v_l1ECUmtVZFdQdtLMpuQpY7Pz2KG_W4mw08C8bRhwc8LZK17feimVYGNKPMODBo_NBDk9kWJZMnpu1CiqVZP9sActj/s681/custom-data.png" /></a></div>
<p>You can even add and remove properties from the <code>_errs.meta</code> object at runtime. So, if your user changes his or her preferences about cats while using your application, you can set <code>_errs.meta.lovesCats = false;</code> when that happens. The tracking script will record the new value <code>lovesCats</code> from that point on whenever an error occurs.</p>
<p>This can be a huge help when debugging your code. Imagine if you could record which user got the error, which action the user was performing at the time, and on which area of your page!</p>
<h2>Other improvements</h2>
<p>There have also been several improvements to the tracking code. Two hard-to-find bugs have been squashed, overall performance has been improved, browser support has been expanded, resilience has been improved in case our servers are in the middle of a hurricane, and the code is much better tested now. All of this while reducing the code size! (Ok, it only reduced by 4 bytes, but it's something, right?) Just to remind you, the code size doesn't really effect you, because the tracking script doesn't come in the way of your page load time at all, giving you maximum performance at all times.</p>
<p>As always, feedback welcome. I can't wait to see what you will do with this ability to record custom data.</p>
<h2>Limits</h2>
<p>The custom data recorded is put into the same store as the one used for <a href="http://blog.errorception.com/2012/11/raw-error-data.html">raw error data</a> and shares the same limits. That is, you can currently put in upto 25 MB of data. Beyond that, older data is purged to make room for the new data.</p>Rakesh Paihttp://www.blogger.com/profile/05275465816567723588noreply@blogger.com11tag:blogger.com,1999:blog-8179719408804246785.post-28551858728547065882012-11-22T15:59:00.000+05:302012-11-22T15:59:44.045+05:30Raw Error Data<p>Since about 2 weeks now, I've been recording information about each individual error occurrence. This data was previously being discarded. I thought, why throw away perfectly fine data, if it can be useful in any way to help in debugging?</p>
<p>A couple of minutes ago, I rolled out a UI to start looking at this data. Now, every error details page will show you all the information that we've captured for every occurrence of the error.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcrwKzn_Jm91Fo0otR1KEn1y0-LCswm2EVdig-OJUITDNlOzdj0TEiPD4CTYgiGYaAZeDwgWHbsVlvqM2ELrIjaYPltgGEVMhc5Toj2NVkn8tBqfaJFVMHkkmjNv1jlgyunt551UvpKp29/s1600/occurrences.png" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" width="600" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcrwKzn_Jm91Fo0otR1KEn1y0-LCswm2EVdig-OJUITDNlOzdj0TEiPD4CTYgiGYaAZeDwgWHbsVlvqM2ELrIjaYPltgGEVMhc5Toj2NVkn8tBqfaJFVMHkkmjNv1jlgyunt551UvpKp29/s600/occurrences.png" /></a></div>
<p>Give it a spin, and let me know what you think.</p>
<br />
<h2>Limits</h2>
<p>The reason I used to discard this data previously is because it grows really big really quickly. So, for now, I've decided to cap the amount of logs stored. <strong>Each project gets 25 MB of storage for these raw logs</strong>. If you end up generating more logs than the limit, older log entries are discarded to make room for the new ones.</p>
<p>Though 25 MB might seem small, it's actually quite a bit. Considering that each log line will realistically be much lesser than 0.5kb of data, you can store more than 50,000 individual log entires before older records get purged.</p>
<p>That said, I've not wholly decided on the 25 MB limit, and am open to change my mind. Feedback welcome.</p>Rakesh Paihttp://www.blogger.com/profile/05275465816567723588noreply@blogger.com0