Every

JavaScript Error- and XHR Log Recording With Every Bug Report

Let’s start with a story. A user story:

A friend of mine called me in the middle of the day with a very strange request. He told me

“Could you come over and help me to fill-in a form”.

I was surprised as filling forms is the easiest thing to do online, isn’t it? Even for not so-tech-savvy people.

So I went to my friend’s home and surprise, it wasn’t so easy! It took me 25 min to debug what was wrong with this website (a government one, in Bulgaria). The problem was missing validation (via XMLHttpRequest).

Of course, I called the agency, expecting everything to go to /dev/null/, but surprisingly they were interested in the problem, so I spent another 25 min explaining the problem and sending them all data they needed. These included:

  1. Screen Size
  2. Browser and OS version
  3. Where exactly the problem occurs
  4. Javascript errors and XHR Logs (pasted in an email)
  5. Plugins installed on my friend’s browser

etc, etc, etc … you know what I am talking about.

It was exhausting.

The perfect bug report

Let’ step aside from the story and think more like developers. What a developer will need to fix the problem quickly, WITHOUT asking the user difficult questions:

  • Screen size, plugins, installed on your browser, URL where the problem happened, OS and Browser version
  • A visual and annotated screenshot showing where exactly is the problem and how it looks like through the user’s eyes with all steps on how to reproduce the bug.

Right?

Wait, something is missing.

The worst thing about most error reports from users is that they happen on the client-side, in front-end javascript, a cruel, cruel place, far away from the developer trying to fix them.

Agreed? That’s why a perfect bug report should contain something else – a browsable JavaScript error- and XHR-logs recorder.

See

Let’s Talk Code: Recorded JavaScript Errors

The Usersnap Console Recorder saves every kind of JavaScript error. You can browse through the web developer console in the Usersnap dashboard, as if you would sit right on your user’s browser!

Every error / log contains a NTP synced timestamp, a full stack including JavaScript source files and line numbers and formatting like the developer console you already know from Firebug

Every debug log issued by console.log, console.info, console.warn or console.error gets properly formatted (including recursive object/array formatting and browsing).

Guaranteed no [object Object] hell during debugging!

Accessing Properties of Undefined/Null Objects

First example which happens quite often in the wild: a fixed element should be aligned by another element by using the top property during scrolling.

However, due to a markup rework, the element #inexistent does no longer exist. This leads to offset() returning null and the property top can no longer be accessed:

function clicky() {
    console.info("Accessing a property of an undefined object");
    console.log("calculating scroll top %d", $('#inexistent').offset().top);
};

Calling Methods of Undefined Objects

Another rework case here: One tries to call a method on an undefined object.

function clicky2() {
    console.info("Calling a method of an undefined object");
    adjust.ScrollBottom();
};

Plain Exceptions

Sometimes you even know during development that something can break – wouldn’t it be great to know it when it actually breaks?

function clicky3() {
    console.info("Throwing an exception");
    throw "Version Mismatch!";
};

XHR Errors

Sometimes, XHRs deliver errors (like 404 Not Found or 500 Internal Server Error). Most of the time, such errors lead to bugs which are very hard to reproduce.

function clicky4() {
    console.info("404 on XHR");
    $.ajax({
        "url": "non_existing.php"
    });
};

Cross-Origin XHRs are troublesome. Image someone changes the CORS header and your cross origin XHR does no longer work from one day to another.

function clicky5() {
    console.info("Cross-Origin on XHR");
    $.ajax({
        "url": "http://facebook.com/cross-origin"
    });
};

XHR and Time Tracking

Recording the Steps During a Checkout

Conversion rates are key in most businesses. Any obstacle for the user can lower your rates – e.g. it takes too long to load a page or you even have an error during checkout.

This short example shows a standard click handler which calls getcheckout.php via XHR. Unfortunately, the second XHR (confirm.php) fails and throws a JavaScript exception. That’s nice, but: the user does not get any feedback. The page just stalls.

function checkout() {
    console.log("check out clicked!");
    $.ajax({
        url: "getcheckout.php",
        dataType: "json"
    }).done(function(data) {
        console.log("Checked out: %o", data);
        confirm();
    });
};
function confirm() {
    confirmService.checkConfirm();
    $.ajax({
        url: "confirm.php"
    }).error(function() {
        throw "internal server error on confirm!";
    });
};

Additionally, you will get a full synced time frame of your user’s action (regardless if the time on the user’s browser is correct or not!). The full formatting support for objects (console.log(“Checked out: %o”, data);) is super convenient for debugging.

Conclusion

Now every developer can have the superpower of understanding what the problem is even on the client-side and stop worrying about “It does not work. Fix it ASAP!” type of communication.

And now every user will be able to report the issues better, because he/she needs just to press one button to report and issue, using the tools he/she knows well, and the magic will happen in the background.

Free licenses for FOSS projects

We at Usersnap support and believe in the FOSS (Free/Libre and Open Source) movement and that’s why Usersnap is free (as in free beer) for any FOSS project to use.

We utilize a number of open source components like nginx, python, rabbitmq, angular and giving back to the community + improving the quality of your projects is a way to say “Thanks”

Your project must meet all of the following criteria to be approved:

  • The project is licensed under a license approved by the Open Source Initiative.
  • The project source code is available for download.
  • Your open source project has a publicly accessible website.

Apply here.

View full post on Mozilla Hacks – the Web developer blog

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

Writing Web Audio API code that works in every browser

You probably have already read the announcement on the Web Audio API coming to Firefox, and are totally excited and ready to make your until-now-WebKit-only sites work with Firefox, which uses the unprefixed version of the spec.

Unfortunately, Chrome, Safari and Opera still use the webkitAudioContext prefixed name. Furthermore, as a result of the spec being still in flux, some browsers use deprecated properties and method names that are not present in standards-compliant browsers: Safari uses the old method names, Firefox uses the new ones, and Chrome and Opera use both. In addition, not all features of Web Audio are already implemented in Firefox yet.

What do we do!?

We don’t want to maintain two or more separate code bases, and feature detection code is cumbersome! Plus we want to write code that reliably works in the future, or at least, works with a minimum amount of changes. Is there a way to satisfy all these constraints at the same time? Probably!

Writing for today (and tomorrow)

First, get a copy of AudioContext-MonkeyPatch by Chris Wilson. This little library will “normalise” the interfaces for you and make it look as if your code is running in a standards compliant browser, by aliasing prefixed names to the unprefixed versions. And it won’t do anything if the unprefixed versions are already present.

Once you include it in your page, you can write in “modern Web Audio API” style, and do things such as:

var audioContext = new AudioContext();

everywhere, including Chrome/ium, Opera, Safari, and —of course!— Firefox.

Also, if new methods such as start are not detected in some nodes, the library will also alias them to their old names. Thus, start is mapped to noteOn, stop to noteOff, and so on.

If you’re porting moderately “old” code (say, a year old) it’s possible that it uses some methods that AudioContext-MonkeyPatch doesn’t alias, because it helps you to write code in the new style. For example, the way to create instances of GainNode used to be

var gain = audioContext.createGainNode();

but nowadays it is just

var gain = audioContext.createGain();

Since the old method names are not present in Firefox, existing code may crash with something like createGainNode is not a function, and you now know why.

There’s a section in the spec that lists the old names and their updated equivalences; be sure to check it out and change your code accordingly. You can also check this article on porting which covers more cases and has many code samples.

Things that are not ready yet

Second, ensure that your project doesn’t use node types that are not implemented yet in Firefox: MediaStreamAudioSourceNode, MediaElementAudioSourceNode and OscillatorNode.

If it’s using, for example, OscillatorNode, you will have to wait until it is supported, or maybe, if you’re really eager, hack in some replacement using ScriptProcessorNode, which allows you to write a node with callbacks that get called periodically, so that your JavaScript code generates or processes audio.

The node parameters you use must also be supported in Firefox too. If they aren’t, you might be able to change them into something “acceptable” for the time being, and count on the talented audio developers to implement those very soon.

For example, up until a couple of days ago PannerNode did not support the default HRTF panning model yet, and attempting to use a PannerNode with that configuration simply resulted in silence or a mono output coming out from that node, depending on the build you used.

Today the support is already present in Nightly, but not quite yet in Aurora. In the meantime, you can explicitly specify 'equalpower' instead:

var panner = new audioContext.PannerNode();
panner.panningModel = 'equalpower';

Keep track

The best way to know what’s going on in the Web Audio API land is to subscribe to the mailing list. Be aware that there might be a bit of high level tech discussions from time to time, and you might not understand it all, but you will learn a lot even if only by skimming through it.

You might also want to subscribe to the umbrella bug that tracks the Web Audio API implementation in Firefox, so that you get alerts when associated bugs get updated or resolved.

Finally, there’s also a list of projects built with the Web Audio API, specifying which ones use the standard AudioContext and which browsers do they work on. If you’re a person that learns by example, it might be interesting to have a look at their source and see how they have resolved the compatibility issues.

View full post on Mozilla Hacks – the Web developer blog

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

Learn and share about new topics every month on MDN

Did you have “expand my technical knowledge” as one of your New Year’s resolutions a few months ago? How’s that going?

How about setting aside a day, or just a few hours, once a month, to teach yourself about a topic related to Web development, and share what you’ve learned with others? Wouldn’t it be fun to do that alongside a bunch other people, either virtually, or maybe in person?

Monthly MDN sprints

Based on discussions among the core MDN community, we’re upping the frequency of MDN doc sprints from “roughly once a quarter” to once per month. To keep them from getting too routine, we’re going to focus on a couple of different topics each month. One will be the topic of the following month’s DevDerby contest; the other will be something related to Firefox OS or open web apps. But since Firefox OS and open web apps are built with open Web technologies, that’s a pretty wide range to pick from. And of course, no one’s going to stop you from working on a different relevant topic of your choice.

As background, a doc sprint is a short period when a group of people come together (virtually or actually, or some combination) to collaborate on writing documentation. If “writing documentation” sounds boring, think of it as a “learning and sharing” sprint. And if you’re not a “words” person, writing example code is a great way to contribute. You’ve probably experienced how much someone can learn from a good code example.

We’ve set dates and some topics for the next three sprints (see below). The first one is just a week away, to squeeze it into March, before Easter weekend.

  • March 22-23: getUserMedia, offline storage
  • April 26-28: Web Workers, Web device APIs (specific ones TBD)
  • May 31-June 1: Topics TBD

These dates are all in the MDN Community Calendar.

How to join a sprint

Sprints run for two or three days, but you can join for whatever part of that you are able to.

  1. Take a look at the wiki page for the sprint you’re joining, for specific details.
  2. During the sprint, hop into the #devmo channel on irc.mozilla.org, and introduce yourself. There will be other sprinters in the channel, unless they’re all asleep.
  3. Login to MDN and get started.

That’s it for participating virtually. In some cases, there will be in-person meet-ups. For example, for the April sprint, there will be a meet-up in the Mozilla Space in Vancouver, British Columbia. (Watch for further details!) Or you can organize a local sprint meet-up of your own, like Fred Bourgeon did in Montréal in February. This could be as simple as tweeting an invitation to meet up at a local coffee shop. Check out our (draft) Doc sprint planning guide if you’re interested.

Meet-up or not, please join us for one or more of the upcoming sprints. It’s a great opportunity to give something back to the Web development community, while expanding your own understanding at the same time.

View full post on Mozilla Hacks – the Web developer blog

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)