Debug anything: Editing variables and restarting functions
Tags: debug, vscode, node, learn
Published: 2020-04-20 07:14:11

---
title: Debug anything: Editing variables and restarting functions
published: true
description: It's possible to replay code blocks in the debugger to see how they behave in different scenarios. Let's look at how to change variables and restart functions in the call stack - a huge time saver!
tags: #debug #vscode #nodejs #learn
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/wlpqmv6fj3xtnb4t08d7.jpg
series: Debug Anything
canonical_url: https://charlesagile.com/debug-anything-editing-variables-and-restarting-functions
---

Previously we've looked at how to [start debugging a simple server](https://charlesagile.com/debug-series-nodejs-browser-javascript) and the ways you can [move around the code](https://charlesagile.com/debug-javascript-typescript-debugger-navigating-with-steps) in the debugger. Today we'll check out two less prominent features. The first one is the ability to edit variables. The second being the ability to replay a function - to restart a [stack frame, to be precise](https://en.wikipedia.org/wiki/Call_stack#Structure) - without restarting the debugger or the application.

While these features might not be super intuitive, they are quite powerful and can save a ton of time. You can try a function buried deep in the call stack with different inputs, without restarting a potentially long and tedious journey.

Let's see how we can use them together to try different scenarios in our usual [tiny server app](https://github.com/thekarel/debug-anything/blob/master/node/index.js).

# Setup

We'll play around with the usual code snippet, go ahead and copy-paste it into an empty file if it's not on your machine yet:

```javascript
const http = require('http');
const url = require('url');

const hostname = '127.0.0.1';
const port = 3456;
const serverUrl = `http://${hostname}:${port}`

const getNameFromReq = (req) => {
  const {name} = url.parse(req.url, true).query;

  return name
}

const getGreeting = (name) => {
  const greeting = `Hello, ${name}!`

  return greeting
}

const server = http.createServer((req, res) => {
  const name = getNameFromReq(req)
  const greeting = getGreeting(name)

  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end(`${greeting}\n`);
});

server.listen(port, hostname, () => {
  console.log(`Server running at ${serverUrl}`);
});
```  

![](https://www.datocms-assets.com/22772/1585563843-deuganything-02-01-code.png)

# Hello, undefined!

Our toy server assumes there is always a query parameter called `name` present in the request. If it's missing, the response becomes "Hello, undefined!":

```sh
> curl http://127.0.0.1:3456
Hello, undefined!
```

Let's use the debugger and see how our `getGreeting` function behaves with different `name` parameters. The fix is trivial, obviously, but let's play along, we're here to see what the debugger can do. 🤓

Let's put a breakpoint on line 15 and hit the server without a name query argument (e.g. `curl http://127.0.0.1:3456`). 

You should see the debugger kicking in and stopping on line 15. 

![](https://www.datocms-assets.com/22772/1586334485-deuganything-03-01-stop.png)

*If you're not confident how to do this, please refer to [Part 1, the basics](https://charlesagile.com/debug-series-nodejs-browser-javascript)*

Make sure the Variables and Call stack sections are both open in the debug sidebar. We'll focus on the local variable `name` for now, which is undefined:

![](https://www.datocms-assets.com/22772/1586334491-deuganything-03-02-undefined.png)

Let's step over the next line (`F10`) and observe the return value of `getGreeting`:

![](https://www.datocms-assets.com/22772/1586334496-deuganything-03-03-returnvalue.gif)

*If you need a quick overview of step over, step into and step out, read [Part 2, Navigating with steps](https://charlesagile.com/debug-javascript-typescript-debugger-navigating-with-steps)*

Ok, no surprises here: if the `name` is `undefined`, the greeting will say `Hello, undefined!`.

# Rewind

Let's re-run this function, this time with a different `name`. We don't need to fire off another request - we can restart the last stack frame:

![](https://www.datocms-assets.com/22772/1586334507-deuganything-03-04-restart.gif)

And we're back at the beginning of the `getGreeting` function 👌

Let's now try what would happen if the name was `null`? We can edit the local variable to fund out:

![](https://www.datocms-assets.com/22772/1586334522-deuganything-03-05-null.gif)

We can try to set a string value - mind the quotes around the value:

![](https://www.datocms-assets.com/22772/1586334543-deuganything-03-06-string-override.gif)

You can override anything local or defined in the [closure](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures), including functions:

![](https://www.datocms-assets.com/22772/1586334558-deuganything-03-07-redefine-func.gif)

*Keep in mind: once you override functions you'll have to restart the process to get back to the original implementation.*

And this is it: you are now able to restart functions in the debugger and edit local and closure values, including strings and functions. Why not play around and see what happens if you restart functions higher up in the stack?

Happy debugging! 🥼