Debug Lesson: the problem from Chrome, CookieStore and var
Tags: webdev, javascript, debug
Published: 2023-04-17 04:41:27

I want to write this post as a lesson from my debug session in step-by-step on how I think and solve the problem I got. I hope it will be useful for someone or myself in the future.

This start when I found some bug at work and after hours of debugging, Not sure if I should call it lucky or unluckily that this bug only happen in my dev environment but as this is from my work's project, I will only use images/code from much more simple example code instead.

## What happened?
So I worked with some web project that using 3rd party library. It's just some analytic tool but in this case, I can't blame the tool itself directly on why it cause the problem.

Whatever, there's some part of the library that have this kind of code
```js
var cookieStore = {
  remove: (key) => {
    // delete cookie with key
    console.log('delete', key)
  }
}

var otherStore = {
  remove: (key) => {
    // delete data in storage with key
    console.log('delete', key)
  }
}

function getStore() {
  // check if using cookie ...
  return cookieStore
}

function removeStore(key) {
  getStore().remove(key)
}

removeStore('some-key')
```

if you try to run this (you can try paste this in console) in Firefox, it will result in `delete some-key`. But in Chrome, it will result in `Uncaught TypeError: getStore(...).remove is not a function`

## Debugging
At first I haven't tried it on Firefox so I don't know it Chrome specific issue.

The first thing I suspect is that `getStore()` somehow result in something without `remove()` function (undefined/null/other object) so I try to inspect on the result of it and see that the `cookieStore` returned from the function is some `CookieStore{}` object instead of object with remove() function `{ remove: ... }`

![checking getStore() result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4hz2li38xs25q3n11l94.png)

Next I check if the line for assignment of the `var cookieStore = ...` is executed or not (as in actual code is much complicate). Turn out value of `cookieStore` before and right after the assignment line are both `CookieStore{}` 

![checking assignment](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xs5z34opvgfs8ptytnxd.png)

Even though it doesn't seem to be re-assign problem, I still check if there is other script that assign the value to this `cookieStore` variable before actual calling to `getStore()`
Using global search, I only find one place which is my assignment

![global search](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tb6liid7vk7tch0vg5lh.png)

Next, I tried to check where this `CookieStore{}` come from. It doesn't seem to have any reference on it anywhere.
Turn out, if you open any page even blank page in Chrome and type to see variable `cookieStore`. You can get the result as `CookieStore{}` already.

Now I'm pretty sure this is cause from a browser and not from any script. I tried to test my script on other browser. 

On Firefox, I see that my script is working fine. Also checking `cookieStore` variable in blank page result in `undefined`

I can now conclude that on Chrome, declaring `var cookieStore` will be override by Chrome default `CookieStore{}` and cause this problem.

## Conclusion
this is exactly what happen when you use `var`. The variable can be shadow from global scope and cause the assignment not working. But this time it is declared by Chrome internally so it become harder to find. 

And the reason this only happen on dev environment because in production, the code is minified so variable name is changed to some minified character and not getting shadowed by Chrome.

To fix this problem. If you can change from `var cookieStore =` to `const` or `let` it will working just fine. But in my case this is code from 3rd party so I need to check with it. Luckily it is fixed in newer version so all I need to do is update it.