Aug 26, 2013

Client side error logging

Everybody uses some analytics service to know how users uses its site. Some programmers even use custom events for this.

Generally it is good idea to know also if your user go out because of js error on your site.

Error logging on client

When something happen on development site programmer usually open developer console and look at errors, but if this happen for remote user we cannot ask each to open console and send us errors.

window.onerror - it is js DOM event handler that catch all programming errors. Some examples of errors:

// syntax error
<script>{</script>

// uncaught exception
<script>throw "some message"</script>

(i think anyone can suggest even more)

window.onerror handler has 3 arguments:

window.onerror = function(message, url, line) {
// message - it is some description of this error
// url - it is url of script that cause error
// line - it is line number in script where error happen
}

Simple example at jsfiddle on clicking button we can see in console messages:

So this is all we need to handle all errors. Second thing it is how to report errors.

On client we have a lot of choices where and how to send requests. For example i will use my tracking example from previous post. I need to include loading code in head as early as possible to get errors in other scripts:

<script>
window.onerror = function(message, url, line) {
 __it("error", message, url, line)
}
</script>

Of course i understand that almost everyone prefer to use something more popular and advanced than just analytics from some blog post. Google analytics has special category for exceptions and someone will write something like this:

window.onerror = function(message, url, line) {
  ga('send', 'exception', {
   'exDescription': 'Error "' + message + '" at '+ url + ' on line ' + line
  });
}

As a basic and free solution this is enough. But also need to say that exists a lot of paid services that solve similar problem but with some nice interface and more advanced features (I do not want publish its url, but if someone need i will add).

Aug 21, 2013

Jenkins ♡ node.js

With my colleague (from InGo) we are building new small startup which will help (we hope) to people to solve “problem of 1000 tabs opened” (usually to read them later).

Our server are built with node.js express application and for CI we are using Jenkins. This post is about how we make Jenkins understand node.js test tools results.

First I have installed some plugins:

  • AnsiColor - this one to have a nicer console output when it is available
  • Jenkins Cobertura Plugin - code coverage
  • Checkstyle plugin - better one for jshint or Violations plugin
  • xUnit plugin or JUnit plugin - test’s results (they uses similar xml files)

How I manage versions of tools

First jenkins pull all sources from repository. Then first build step, make npm install and I have all my dependencies installed (dev too).

In package.json in devDependencies I have all tools that need to run tests, get metrics and so on.

I think it is required to point: with node.js in current state there is no right way, but there is the most convenient way for me in our project at current state. So if I will found something more convenient I will switch to that way.

To do not spend time each time to edit jenkins job I created Makefile and added tasks to it.

Test results with xUnit plugin

For tests we are using mocha and should.js (and supertest for http requests). This is a job to get xUnit compatible xml:

test-jenkins-xunit: @NODE_ENV=test ./node_modules/.bin/mocha \
    --recursive \
    --check-leaks \
    --reporter xunit \
    $(MOCHA_OPTS) 1> results/xunit.xml

In build steps I add shell script step:

make test-jenkins-xunit 

And in post build steps:

Jenkins xUnit plugin usage

JsHint warnings/erros with Checkstyle plugin

After jshint 2.X.X was released behaviour of default reporters was changes. In previous version –show-non-errors makes in output xml (with checkstyle reporter) show not used variables and globals as warnings. Now it uses own reporter. To return old results I fill simple checkstyle reporter with old and new code.

Makefile task:

jshint-jenkins:
    ./node_modules/.bin/jshint --reporter=checkstyle-reporter.js $(JS) 1> results/checkstyle.xml

Now need to run this task at shell step and point Checkstyle plugin to file with results:

And now we see nice and convenient chart in our job:

JsHint warnings/errors with Violations plugin

This section outdated (I prefer Checkstyle plugin) but if you want to use Violations plugin.

First again Makefile task:

test-jenkins-jslint:
    ./node_modules/.bin/jshint $(JS) --jslint-reporter 1> results/jshint.xml || exit 0

And how to use it in jenkins build step:

make test-jenkins-xunit 

I added ‘exit 0’ because it return 1 if anything found and build step will fail.

Exists one problem with Violations plugin and xml that produced by jshint. Because it uses relative path you cannot see in job report where actual problem is. I saw several posts about it and nobody publish solution. After previous build step i have added new one that fix xml:

sed -E "s?<file name=\"(.*)\?\">?<file name=\"$WORKSPACE/\1\">?" results/jshint.xml > results/jshint-fixed.xml

This will replace relative paths in name attribute to absolute that Violations Plugin can handle.

Now after build step:

Jenkins Violations Plugin usage

Code coverage with Cobertura plugin

Makefile task:

test-jenkins-cov:
    @NODE_ENV=test ./node_modules/.bin/istanbul cover --report cobertura --dir
        ./results ./node_modules/.bin/_mocha -- \
        --recursive \
        --check-leaks \
        --reporter $(REPORTER) \
        $(MOCHA_OPTS)

Build step is very simple:

make test-jenkins-cov

Last thing after build step:

Jenkins Cobertura Plugin Usage

Now I press ‘Save’ and run this job to see reports (I hope You don’t forget to add repository to this job). Click on job name:

Jenkins results

When I click on any of this charts i can see more detailed report. This one from Violations Plugin that you can see when click on file in report (and you will not see this if you do not fix problem with relational paths).

Example of Violations

That is all! I hope this post will help to somebody. I decide to write it because there is no similar post that describe whole process.