Cache Context Drupal 8 — A Buggy Code Story!

In last two blogs Cache Context — Part 1 and Cache Context — Part 2, we discussed about what is cache context and how we can create and use cache context. In this blog we will discuss about the side effect if we don’t use the cache context properly in our custom code with an example.

In the recent project, I had to show few links to the user (user specific links) and name of the user as well. Something like below image with red marker

Here View Profile and Edit Profile link should take the user to user/uid and user/uid/edit page respectively and the Admin is the current user’s username. Very simple, we just created a custom block and assigned that block to the appropriate region. Below is the sample code -

All looks good but then came the actual problem. When QA started testing it and clicked on links, got the access denied message. Strange! We thought of permission problem or something :) but with some debugging found out that its caching problem.

Here is the detail — As soon as the first user logged-in the site, block got cached (and thus the content). So if a user has uid say 5, then the links of the block will be user/5 and user/5/edit. Now when another user logged-in the site, user saw the cached version of the block. So if this (second logged-in user) use has uid say 7, it will see the links as user/5 and user/5/edit (cached version of first user) and thus access denied (as editing another user profile and theoretically permission problem :)).

So let’s say we have two users — user2 and user3. Now first user2 logins in the site and see the block result as -

Looks good. Now user3 logins in the site and see the block result as -

We can clearly see that for the user3, we are seeing the same block (same username) as block is cached.

This whole scenario was because we didn’t properly used the cache context on our custom block. So how we solved this? We just simply used the proper cache context in our custom code and problem solved. In this case we need to cache/vary the content per user and thus need to use the ‘user’ cache context.

So in this case, just adding current cache context to block worked.

Drupal 8 provides great power with cache context but then again as per spiderman movies -

With Great Power Comes Great Responsibility