Debugging Node.js Azure Web Apps (Websites)

Deploying Node websites to Azure is really simple with their Git deployment feature. However, sometimes debugging problems can be challenging. Here are some of the tricks I’ve discovered for diagnosing problems with Node apps in Azure.

Viewing Application Output

To view application logs (a.k.a. stdout and stderr) from your app, you can turn on Application Logging from the management portal’s “Configure” tab.

Note that application logging will only be turned on for 12 hours, so if you need to be able to see historical logs, you need to save them to a file from within your application.

To view the logs, you can go to the Kudu dashboard at “<yourazuresite>.scm.azurewebsites.net”. Select either CMD or PowerShell from the “Debug console” menu, then navigate to LogFiles/Application. Scroll until you find index.html and click the download button (which will display it in your browser).

From there you can scan through for the logs from the time period you’re interested in and click the “log” link. Notice that the logs are split by “stdout” and “stderr”.

Other IIS Logs

To enable other IIS related logs, go to the “site diagnostics” section. These settings can be useful for debugging IIS level issues.

You can find these logs in a few different folders under “LogFiles” in the Kudu dashboard.

Using Node Debugger

Node Inspector is a really useful tool for digging into problems with your Node app. I’ll often spin it up locally if I’m investigating an issue that isn’t easily revealed with a console.log statement. However, sometimes bugs only reproduce on the server. If that happens, using the version of Node Inspector built into Azure can be really useful.

Enabling Websockets

Node inspector uses WebSockets to communicate between the UI and the debugger backend. Since Azure Websites doesn’t enable them by default, you’ll need to manually enable WebSockets in the “Configure” tab of the management portal.

Check Your Web.config

If you deployed your site with a Git push, Kudu should have generated a Web.config with correct configuration for debugging. If not, I have a generalized Gist that I use as a starting point. Just change the references to bin/www to reflect the correct entrypoint for your app.

Enable Debugging

To enable debugging, you can either modify your Web.config or create/modify an iisnode.yml file.

In the Web.config, it looks like this:

1
2
3
4
<!-- You'll find a placeholder near the end of the generated Web.config -->
    <iisnode debuggingEnabled="true"/>
  </system.webServer>
</configuration>

Or in iisnode.yml, it looks like this:

1
debuggingEnabled: true

The advantage of using iisnode.yml is that you don’t have to worry about a new deployment generating over your existing configuration. It’s also worth noting that you can configure a bunch of other settings in both the iisnode.yml and the Web.config.

Testing Out the Debugger

To use the debugger, go to your azure website, and append the entry point path, and /debug. So for example, if your entry file was server.js, you’d go to <yourazuresite>.azurewebsites.net/server.js/debug

If everything’s configured correctly, you should see the debugger. You can set breakpoints and debug the route handlers for your app.

Keep in mind that when you set a breakpoint, the entire app is halted. This means you probably don’t want to attach the debugger to an app that’s serving production traffic.

Mocha Error - this.timeout Is Undefined

If you’re using an ES6 compiler like TypeScript or Babel, you may have run into an odd error when you tried to call this.timeout() from your Mocha tests.

1
2
3
4
it("foo", (done) => {
  this.timeout(1000);
  // test some things
});

If you look at the compiled output, the source of the problem becomes evident. The compiler is taking the value of this from outside the test. This is also the behavior you’d see if you used a JS engine with ES6 support.

1
2
3
4
5
var _this = this;
it("foo", function(done) {
  _this.timeout(1000);
  // test some things
});

Arrow functions specify that the scope of the “this” variable inside the function is the same as its scope outside the function. Unfortunately, in this case, that isn’t what we want. We want “this” to be the Mocha object that we can call this.timeout() on.

Switching back to the old-school function style fixes the problem:

1
2
3
4
it("foo", function(done) {
  this.timeout(1000);
  // test some things
});

And there you have it. Be careful with “arrow” functions in Mocha tests. They’re fine to use in most cases, but if you need to call this.timeout(), make sure you switch back to the old-school function syntax.

Viewing All Versions of an NPM Package (Including Pre-Release)

If you want to view all released versions of an npm package, there’s an easy way to do it:

npm show react-native@* version

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
react-native@0.0.0 '0.0.0'
react-native@0.0.5 '0.0.5'
react-native@0.0.6 '0.0.6'
react-native@0.1.0 '0.1.0'
react-native@0.2.0 '0.2.0'
react-native@0.2.1 '0.2.1'
react-native@0.3.0 '0.3.0'
react-native@0.3.1 '0.3.1'
react-native@0.3.2 '0.3.2'
react-native@0.3.3 '0.3.3'
react-native@0.3.4 '0.3.4'
react-native@0.3.5 '0.3.5'
react-native@0.3.6 '0.3.6'
react-native@0.3.7 '0.3.7'
react-native@0.3.8 '0.3.8'
react-native@0.3.9 '0.3.9'
react-native@0.3.10 '0.3.10'
react-native@0.3.11 '0.3.11'
react-native@0.4.0 '0.4.0'
react-native@0.4.1 '0.4.1'
react-native@0.4.2 '0.4.2'
react-native@0.4.3 '0.4.3'
react-native@0.4.4 '0.4.4'
react-native@0.5.0 '0.5.0'
react-native@0.6.0 '0.6.0'
react-native@0.7.1 '0.7.1'

However, this doesn’t show pre-release versions. If you want to see everything, there’s an equally easy (but undocumented) command:

npm show react-native versions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
[ '0.0.0',
  '0.0.5',
  '0.0.6',
  '0.1.0',
  '0.2.0',
  '0.2.1',
  '0.3.0',
  '0.3.1',
  '0.3.2',
  '0.3.3',
  '0.3.4',
  '0.3.5',
  '0.3.6',
  '0.3.7',
  '0.3.8',
  '0.3.9',
  '0.3.10',
  '0.3.11',
  '0.4.0',
  '0.4.1',
  '0.4.2',
  '0.4.3',
  '0.4.4',
  '0.5.0-rc1',
  '0.5.0',
  '0.6.0-rc',
  '0.6.0',
  '0.7.0-rc',
  '0.7.0-rc.2',
  '0.7.1',
  '0.8.0-rc' ]

This is super useful for finding what beta/pre-release versions of a package are available.

You can also run npm show react-native versions --json for machine readable output.

Watching Custom Directories From the React Native Packager

React Native projects ship with a packager that builds and serves your JavaScript resources. It also watches your project folder for changes, and rebuilds. However, if you link a Node module from a different directory, the packager won’t see changes that are made to that package.

It’s fairly easy to specify custom folders for the packager to watch. Since the React Native client sets up an npm start command when it generates the project, you can simply modify that script to watch additional folders.

1
"start": "node_modules/react-native/packager/packager.sh --root ~/custom-package/"

Unfortunately, when you launch the project in Xcode, it runs the packager directly, rather than running the npm start command, but if you manually run npm start from a terminal window, React Native will use that rather than launching a new instance of the packager. I have an issue opened on the React Native project, suggesting that they run npm start from Xcode, but we’ll see if it goes anywhere.

React Native: Fix for “Invariant Violation: onlyChild Must Be Passed a Children With Exactly One Child”

I recently ran into a new (to me) error in React Native.

1
Invariant Violation: onlyChild must be passed a children with exactly one child

I couldn’t find any documentation on it, so I thought I’d share what I figured out.

All of the “Touchable” components in React Native do an onlyChild check on their children, which throws an error unless there’s exactly one child.

1
2
3
4
return (
  <TouchableHighlight>
  </TouchableHighlight>
); // Error: onlyChild must be passed a children with exactly one child

Adding a child to the TouchableHighlight will fix the error

1
2
3
4
5
return (
  <TouchableHighlight>
      <Text>foo</Text>
  </TouchableHighlight>
); // OK

But adding multiple children will also cause an error

1
2
3
4
5
6
return (
  <TouchableHighlight>
      <Text>foo</Text>
      <Text>bar</Text>
  </TouchableHighlight>
); // Error: onlyChild must be passed a children with exactly one child

A quick search through the React Native code reveals the components that verify onlyChild:

  • TouchableBounce
  • TouchableHighlight
  • TouchableOpacity
  • TouchableWithFeedback

Hopefully React Native can eventually provide a better message for this issue, but until then, at least this blog post should pop up when you Google the error.

React: this.state Is Undefined

I ran into this today, so I’m writing it down in case it helps someone else.

Running something like the following, I found that this.state was undefined during render.

1
2
3
4
5
6
7
8
9
class MyComponent extends Component {
  getInitialState() {
      return { count: 0 };
  }

  render() {
      return <div>{this.state.count}</div>; // Error: this.state is undefined
  }
}

After a little searching, I found the release notes for React 0.13.0-beta-1, where they explained that ES6 classes should set initial state in the constructor, rather than defining a getInitialState method.

1
2
3
4
5
6
7
8
9
class MyComponent extends Component {
  constructor() {
      this.state = { count: 0 };
  }

  render() {
      return <div>{this.state.count}</div>; // Yay, it works!
  }
}

Pretty simple, but not immediately obvious if you don’t know about it.

Configuring an Existing Octopress Site on a New Machine

Every time I set up a new machine, I have to figure out how write posts on my Octopress blog. I usually follow these instructions, but have to tweak them slightly to work for me. I fanally decided to write down the exact steps I use so I don’t have to figure them out every time. Hopefully it’s useful for someone else as well.

Step 1 – Run Octopress setup

1
2
3
4
5
6
7
git clone git://github.com/imathis/octopress.git octopress
cd octopress    # If you use RVM, You'll be asked if you trust the .rvmrc file (say yes).
ruby --version  # Should report Ruby 1.9.3
gem install bundler # On Linux/OSX you may need to run "sudo gem install bundler" instead
bundle install
rake install
rake setup_github_pages

The main purpose of setting up Octopress like this is to get the main layout configured correctly.

Step 2 – Reset to your blog’s branch tips

1
2
3
4
5
6
7
git fetch origin source
git branch --set-upstream-to=origin/source source
git reset --hard origin/source
cd _deploy
git fetch origin master
git branch --set-upstream-to=origin/master master
git reset --hard origin master

Obvious Code

A week or two ago, I got this feedback on a code review:

You’re using foo ? foo : "" here. It would be shorter and more obvious if you wrote it as foo || ""

This was valid feedback, and I updated the code.

After I’d checked in my changes, I got the following IM from a senior member of my team:

I see you did foo || ""? What does the || mean?

:)

This was a good reminder of two things:

  • “Obvious code” is a subjective concept
  • No matter how experienced you are with something, you’ll still find blind spots from time to time

P.S. If that syntax is also new to you, it’s taking advantage of how JavaScript does “or”. A JavaScript or returns the first truthy value, or the last value if none are truthy:

e.g. (false || 0) === 0 and (0 || false) === false and (foo || "") === "" (assuming foo is “falsey”)

Many JavaScript developers use this behavior as a shortcut for setting default values, because null and undefined are falsey.

Dynamically Configure Your Git Email

This post is the second in a series on tuning your Git environment. The first post on customizing your git log isn’t a prerequisite, but may be useful.

Managing Multiple Commit Emails

If you use Git at work and in your personal time, managing the email you use for commit messages can be tricky.

When my previous team first started using Git, I had several instances where I accidentally committed to our team repository with my personal email address. This wasn’t a big problem, but it made the repository history look a little messy, and it meant my picture didn’t show up properly in the UI tools.

Simple Fix: Manually Configure Email Per Repository

My first solution was to remove the global configuration for my email address:

git config --global --unset user.email

This way when I committed into a fresh repository, I’d get a warning that I hadn’t configured my email.

1
2
3
4
5
6
7
8
9
10
11
12
13
Your name and email address were configured automatically based
on your username and hostname. Please check that they are accurate.
You can suppress this message by setting them explicitly:

    git config --global user.name "Your Name"
    git config --global user.email you@example.com

After doing this, you may fix the identity used for this commit with:

    git commit --amend --reset-author

 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 foo1

Then I just had to configure my email locally for that repository:

git config user.email will@itsananderson.com

And update the commit with the right author data:

git commit --amend --reset-author

Medium Fix: Add Some Git Aliases

Running through those steps for every new repository quickly becomes tedious, especially when you like to spin up GitHub projects for every idea that pops into your head.

To simplify things, I first created an alias for the git commit --amend --reset-author command. I called it cara for “Commit Amend Reset Author”, but you could call it whatever you’ll remember. With that alias, it’s super quick to fix a commit if I create it with the wrong author email.

The next thing I aliased was a script to guess the author email based on the repository URL. I created a script and put it in ~/.git-scripts/email-guess.sh (again, call it whatever you’ll remember).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash

remote=`git remote -v | awk '/\(push\)$/ {print $2}'`
email=will@itsananderson.com # default

if [[ $remote == *github.com:Microsoft* ]]; then
  email=wiand@microsoft.com
fi
if [[ $remote == *itsananderson.visualstudio.com* ]]; then
  email=will@codeawhile.com
fi

echo "Configuring user.email as $email"
git config user.email $email

The script isn’t exactly a masterpiece, but it gets the job done. Feel free to copy and modify it to meet your needs.

For the script to be useful, I aliased it as git email-guess:

git config --global alias.email-guess \!". ~/.git-scripts/email-guess.sh" ""

So now when I clone a new repository, I just git email-guess to set the email. If I forgot to do it before my first commit, I follow it with git cara to fix that commit’s author.

Advanced Fix: Full Automation

Reducing the work of author email management to only 1 or 2 commands is nice, but I wanted to eliminate it altogether. This is where Git hooks came in handy.

You can configure a Git hook manually for each repository, but again, we want this to be automated. To do that, you’ll want to modify the template hooks Git uses when it creates new repositories.

On Windows, these hook templates are located somewhere near C:\Program Files (x86)\Git\share\git-core\templates\hooks. On OS X and Linux, they should be somewhere under the Git directory. Running which git or cat `which git` should point you in the right direction.

Once you locate the template hooks directory, create a file called post-checkout with the following contents:

1
2
3
4
5
#!/bin/bash

if [[ $1 == 00000000000* ]]; then
  git email-guess
fi

All this does is test whether Git checked out a freshly cloned repository (thus “previous SHA” is all zeros). If so, it runs git email-guess to set up the correct author email.

Wrapping Up

So that’s the full rundown of my email configuration setup. As I said in the previous post, you should take this as an example that you can customize it to fit your needs.

You can find most of my Git configuration in my git-better repository on GitHub.

As one example, there are many other Git hooks that you can take advantage of. Take a look to see if there are any that you could use to automate a frequent task.

Git

Customize Your Git Log Format

Over the last few months, I’ve been learning about woodworking in my spare time. As I’ve read articles and watched YouTube videos, I’ve noticed that the most successful woodworkers have a detailed knowledge of their tools. Not only do they know how to use and maintain the tools of their craft, but they’re not afraid to modify them to better serve their needs. When they need a custom tool or jig to speed up their work, they make one. Watching and reading about these craftsmen and their tools, I’ve noticed parallels in my full time craft: Software Development.

In the next few posts, I’ll share some of the software “jigs” I’ve created to make myself more efficient. The primary focus posts will be configuration and customization of Git.

Git Log: Your Own Personal Journal

If you’re not already aware, your Git log is a critical tool for working with source control. Because your memory’s not perfect, a good log helps you recall what you’ve done, and the motivation behind it.

I’ve written before about writing good commit messages, as has David in his series “Committed to Good Commits”. If your commit logs are sprinkled with gems like “did stuff” and “it finally works!”, you’ll want to check out those posts.

Choose Your Details With --format

Depending on what you’re looking for in your log, you may want different levels of detail. The Git log documentation has a full list of the built-in formats.

For example, if you’re trying to find the SHA for a recent change, you may just want to see the SHA and the commit subject for each commit. In that case, git log --format=oneline or git log --oneline is what you need.

If you need verbose output, including the full message and author info, --format=medium is a good option.

Finally, if you want every single detail from the commit, --format=fuller will give you that.

If you want to make any of these formats your default, you can do so with the following command:

1
git config --global format.pretty oneline # replace oneline with the format you want

Limit Results With -n

If you only want to see the last few commits, you can use the -n flag. The more verbose version is -n <number> (e.g. -n 5 to show the last 5 commits).

Alternatively, you can use an even quicker shortcut. Just use -<number>. For example: git log -5 will show the last 5 commits.

Fully Customize Your Log Output

Depending on how you use your commit log, you may find that no built-in log format exactly fits your needs. What I’ve found is that the verbose formats are too hard to scan through, and the succinct ones don’t have vital info.

To solve this problem, I created a custom log format, which I use almost exclusively.

You can configure my format with the following command:

1
git config --global format.pretty format:"%C(auto)%h %d%Creset %s%n%Cgreen%ad%Creset %aN <%aE>%n"

The output looks like this:

This format also works with the --graph flag:

What I like about this format is that it only uses three lines per commit, but it has all the information I care about. I also inserted color codes for the various parts of the message, which makes it even easier to grok.

In Conclusion

Hopefully these examples give you some ideas about what you can do to customize your commit log. Don’t feel like you need to use my custom log format as-is. The whole point is to customize it to fit your needs.

If you want to test out different custom formats quickly, you can pass them directly to git log like so:

1
git log --format=format:"%C(auto)%h %C(green)%aN%Creset %s"

You can find the different placeholder options in the same Pretty Formats section of the Git Log documentation.

Git