Archive for February 2013

Disabling the cache in Chrome

I like Chrome a lot. I especially like its developer tools, which finally persuaded me to leave Firefox and Firebug behind. However one thing which persistently bugs me is how aggressively it caches assets. Generally speaking, its caching is excellent. We don’t want to be retrieving files when we already have them cached. During development this is something of a pain in the arse, as I have to fight against the cache to see updates to, say, javascript files.

One way around this that I sometimes see proposed as a solution in to version javascript files, ie include a version number in their filename. This does ensure that the browser will always retrieve the latest copy of the file, but it’s not great when actually developing. Having to increment the version just to add a console.log statement, for example, isn’t great, and arguably slower than just clearing the cache every time. In fact clearing the cache isn’t all that hard. I’ve collected a few methods together as I see this is something that a lot of people are frustrated by.

Keyboard Shortcut

CTRL-SHIFT-DEL. Job done, you cunning swine. Take the afternoon off!

Network Tab

Right-clicking in the Developer Tools Network tab gives an option to clear the cache. Like this:

Kill it. Kill it with fire

Alternatively, just disable the damned thing altogether. This is available via the often-overlooked Settings for Chrome’s Developer Tools. To access these, click the little cog at the bottom right of Developer Tools, as circled below:

Then, on the General tab, there’s an option to disable the cache:

Check that, and you’re golden. Take the rest of the week off. Hell, quit your job! It can’t possibly get better than this.

Here’s a skateboarding duck:

EPiServer Access Rights Wrongness

Recently I had a bug raised on an EPiServer build which described an error message I’d never seen before. When attempting to assigned new group rights to a particular branch of the page tree, the admin user was faced with this error message:

After reflecting the code out I found the error message in a catch block around a database transaction. To understand what was happening, it’s necessary to have a bit of knowledge about how EPiServer manages its access rights.

What lies beneath

tblAccess

This table keeps track of user/group access rights. It contains records for each user and group stored against a page id. Crucially, the page id has a constraint on it – the pageĀ must exist inĀ tblPage. This was the underlying cause of the error message – a non-existent page id was being inserted into the table. But how could that happen?

tblTree

This table describes the page hierarchy. It records the page id of a page against the page id of its children, along with an integer indicating the level of nesting. When access rights for a branch of the pagetree are updated, two things happen:

1) The current rights for the user/group are removed from tblAccess. The records are deleted using a set of records from tblTree as a master list of pages included in the branch.

2) New rights for the user/group are assigned. These are written to tblAccess, again using a set of page ids obtained from tblTree. However, there is no constraint on tblTree. As a result, the table can contain a page id for a non-existent page. The upshot of this is that when tblAccess is updated, it attempts to write an invalid page id, which fails, resulting in the error message above.

This should never happen

Although tblTree should ideally have a constraint on it, the above scenario should never happen. Left to its own devices EPiServer will take care of its table structure, so the situation decsribed here looks like the result of a manual database manipulation. Someone, at some point, has hand-deleted some pages. This illustrates the pitfalls of directly manipulating CMS data nicely – table constraints will have led the way to deleting all references to the deleted pages, but tblTree has been missed. This is a lesson we should all know already, but it never hurts to be reminded why the lesson exists.