JavaScript, Web

Logging JavaScript exceptions. Custom solution + ELMAH

Development team was reported about critical bug in production. First thing they did was checking server logs but they were empty. Impossible! On the other hand the client sent screenshot with error alert.
Have you ever experienced such scenario? It happened to me many times. And it’s nothing extraordinary – the more code on the client, the more probable to commit a bug. The worst thing is that’s so hard to track such bugs. After all it came out that’s not that hard. Here’s my solution:

  1. (Optional but recommended: use ELMAH. It adds a nice error log and page to browse already caught errors + some extra information about context of such errors)
        Install-package elmah
    or if using ASP.NET MVC
        Install-package elmah.mvc
  2. Listen for client-side errors and send them to the server (custom errorLogging.js script):
    jserror3
    Please note, that the code above does not work on IE7 and below (just to keep it simple). IE supports JavaScript stacktrace from version 10+ that’s why there is “if” clause between lines 16-18.
  3. Add back-end code to listen for exception logsjserror4
    You could use MVC or WebAPI controller, but handlers feels more like infrastructure. If you don’t want to use ELMAH, then replace line 36 with your logging mechanism (or “throw jsException“).
  4. Create exception type specific to JavaScriptjserror5
    It’s particularly important to override ToString() method as it’s used by ELMAH to dump exception details.
  5. Connect it all together: add script reference to errorLogging.js and register JavaScriptErrorHandler class in global.asax.cs

And there it is! If you don’t want to do it yourself go to my github page and download a working sample: Blog.ClientSideExceptionCatching

After playing for some time here are the results. As you can see both server-side and client-side errors are kept together with the time they occurred.
jsError
If you go deeper then you see exception details (message, stacktrace).

jsError2_1

jsError2_2

This is something that we get by our hands. Elmah also gives us a very useful gift as it logs all server variables, including HTTP_USER_AGENT that tells us what browser was used on the client. You don’t need to ask the user for such things. Handy!

Off-topic/final points

  • First I tried jsnlog but failed. It forced me to use Common.Logging and was not working out-of-the-box.
  • Beware of Internet Explorer – it generates localized exception messages (see the first elmah screenshot) and may not support stack trace
Web

Getting started with PJAX with ASP.NET MVC

What is PJAX?

Pjax is a library that loads HTML from server side and puts it into a given placeholder (it could be a simple ‘div’). Underlying communication is done with AJAX so it is very fast and enhances a lot the browsing experience. But what is special in pjax?

pjax = pushState + AJAX

The best thing in it is that it utilises HTML5 History API (pushState API). It means that while loading only a part of a page we can completely change browser’s URL and use browser’s history to navigate through the pages. Awesome! To see live demos check out: https://github.com/defunkt/jquery-pjax or http://pjax.heroku.com/ (or wait for a movie in the end of the blog post).

HTML5 History API

HTML5 History API or pushState API is something new in Web development world. Oldschool history API was meant only as a way of going forward and backward in browser’s history, so the thing it could be used was to implement “<= back” and “next =>” buttons:). Now the thing is completely different. HTML5 brings “pushState” method that stores a magic triple into history engine: the URL of the state, the title of the state and some additional data.

history.pushState({name: 'state1'}, "New URL", "newpage.html");

Any execution of the method forces the browses to change the URL and the title of the page but nothing more – it even does not chech whether a page with the given URL exists. The user can manually change the content of the page after running the method.
With pjax it all is wrapped in the form of jQuery plugin and the usage is extremely straightforward.

Real usage

HTML5 History API is commonly used when two pages with different URLs differs with only a small piece of information, sharing all the heavy layout, javascript files etc. Loading of the resources and rendering the page is expensive so the solution is to change the way some hyperlink works – they should modify history and URL (with pushState) and load (by AJAX) only the missing part of the page. Loading the page could be supported by showing a custom progress bar or firing other fireworks like animations etc.
The most popular usage (in our development environment) is GitHub directory tree which is extremelly fast and has a nice effect during the navigation. Facebook uses the API to load pages leaving the chat windows open for that time. GMail… is not using it, but I’ll left it for the finish.

ASP.NET MVC implementation

To implement our efficient application we need to provide two kinds of layouts: one complete layout and another only for PJAX requests. Anytime the page is loaded normally by the URL we should load the full layout but if there was PJAX request we should take the lighter one. Here is the code that should be a wrapper for our layout (i.e.: _ViewStart.cshtml):

@{
     if (Request.Headers["X-PJAX"] != null) {
          Layout = "~/Views/Shared/_PjaxLayout.cshtml";
     } else {
          Layout = "~/Views/Shared/_Layout.cshtml";
     }
}

Because PJAX puts a special header ‘X-PJAX’ into its calls we can distinguish them as  done in line 2.

The _PjaxLayout.cshtml could be implemented as following:

<title>@ViewBag.Title</title>@RenderBody()

The only responsibility here is rendering the page’s title and body (without any layout because it would be injected into the given placeholder).
The client side is even more simple. The only thing you need to do (despite adding script references) is registering pjax:

$('a').pjax('#main_content');

In the script above we said that for each hyperlink (‘a’ element) we should override its normal functionality and instead use PJAX to load the target document (‘href’) to a placeholder with id ‘main_content’. I’d say it couldn’t be simpler.
Here are some packages with ASP.NET MVC default applications utilizing PJAX. In the second one I use some effects (like animation and splitter) to enrich user experience:

PjaxMvcDemo.zip
PjaxMvcDemo_fireworks.zip

And the video showing PJAX in practice…

 

Pjax alternative

Some of you may think that it’s not mandatory to use PJAX or even pushState to achieve the same effect. And I’d say “Yes and No” at once. Here is the role of GMail mentioned before – it does not use pushState but is efficient and leaves the chat window openned! It uses something called HASH-HACK. When we add ‘#’ sign to the URL the browser thinks that we navigate to a region in the same page and it does not load any other page. That’s why the URL address changes but the chat window stays openned. The partial page load is done in a way similar to the PJAX version.
The biggest disadvantage of that hack is that URL must contain ‘#’ sign and because of that cannot be rated by any Search Engine. For e-mail client it is sufficient, but that’s all.

Summary

PJAX is an excellent jQuery plugin that simplifies usage of HTML5 History API. It is used to improve performance of the application and experience of a user dealing with it.
Have a nice time playing with it.

PS: Here is a reference to a blog post of the inventor of the way we connect PJAX to ASP.NET MVC 3: http://biasecurities.com/blog/2011/using-pjax-with-asp-net-mvc3/

Portfolio

SemanticDataNavigator–Web 3.0 Data Browser

This is the title of my master thesis project. The whole idea of the project is based on the concept of Web 3.0 (Semantic Web). It assumes that in future Internet all the data will be connected and thus every object could be described in a way that is clear not only for a human but also for a computer.

The main goal of the project is to let the user browse semantic data coming from various repositories. Users can find interesting object (by text search or query editor) and then see full report gathering all the information about the object. Reports are presented using views created by the users. Objects classified as “places” have their own view, “poets” have there own view, which is derived from the view of “people”. While browsing the data, user can do some actions appropriate to the class of objects (i.e. “places” can be shown using Google Maps). Moreover he can build queries about another data. The following short video shows some features of the application.

The project is similar to Freebase but it has some considerable advantages:

  • Users can create queries interactively using the context menu action as well as using the query editor
  • Data are not dependent on concrete ontology
  • Data can be retrieved in parallel from various repositories (providing SPARQL Endpoint)

The project is done as a web application created using ASP.NET MVC 3. The library used to built semantic data layer is dotNetRdf.

At the moment there is no public version of the application.