Floobits Atom: Fixing Bugs (in Atom)

02 Aug 2016 by ggreer


Our Atom package has been improved significantly since it was originally announced. Several of these improvements were thanks to fixes in Atom.

Fixing Video Chat: Content Security Policy

When Atom 1.7 was released, users complained that video chat showed a black screen. Our plugin hadn’t changed, so I suspected something in Atom was responsible. I soon tracked it down to Content Security Policy headers. The new version of Atom used a new version of Electron, which was based on a newer version of Chromium. The newer Chromium had stricter CSP behavior, such that self no longer included blob:. I found the relevant code in Atom and submitted a pull request. It took a while for the Atom team to merge it, but the fix is now in Atom 1.9.

Fixing Crashes: Avoiding NODE_ENV Erasure

Another issue that had been plaguing our Atom package was random React-related crashes. None of the stack traces involved any Floobits code, so it took me a while to figure out the root cause. Try to find the common thread in all of these issues:

I went gallivanting through the React code and managed to figure it out. React was starting up in production mode, then later switching to debug mode. React only initializes certain debugging data structures if it starts up in debug mode. Starting in production and switching to debug mode caused it to attempt to access object properties that didn’t exist. Oops.

React chooses modes by checking process.env.NODE_ENV. If it’s set to “production”, it will run in production mode. Otherwise, it uses debug mode. Atom initializes NODE_ENV to “production” in src/initialize-application-window.coffee. Something must change it later.

I finally tracked it down to src/environment-helpers.js:

70 // Fix for #11302 because `process.env` on Windows is a magic object that offers case-insensitive
71 // environment variable matching. By always cloning to `process.env` we prevent breaking the
72 // underlying functionality.
73 function clone (to, from) {
74   for (var key in to) {
75     delete to[key]
76   }
77 
78   Object.assign(to, from)
79 }

This clone() function is called when running atom from the command line. If Atom is already running, it replaces the existing environment with the new one, which usually lacks NODE_ENV. Oops.

I created an issue describing the problem, soon followed by a pull request to fix it.

A Side Note: Node’s process.env

While working on the NODE_ENV issue, I discovered some surprising behavior in Node’s process.env. Look at this REPL interaction:

> process.env.TEST = undefined
undefined
> process.env.TEST
'undefined'
> typeof process.env.TEST
'string'

That’s right: process.env stringifies any value you try to set. The only way to un-set an environment variable is to delete it. This isn’t as crazy as it first sounds. Environment variables can only be strings. Still, such behavior is not obvious. It’s documented, but let’s be honest: Developers only read docs when they don’t think they understand something. If process.env looks like an object and walks like and object and quacks like an object, developers will think it’s an object. A better solution would be to have explicit process.setenv() and process.getenv() functions.

Conclusion

Fixing these bugs taught me some new things about browsers, Atom, and Node.js. No matter how much experience one has with these software projects, there’s always plenty more to learn. To debug software is to be constantly reminded of one’s hubris.

Lastly: If you’ve tried Floobits for Atom before and found it lacking, I urge you to check it out again. In addition to these bug fixes, the UI has been revamped. It all makes for a much better experience. And if you do find issues, please report them. User feedback is incredibly helpful!


About the Author

I’m Geoff Greer, CEO & co-founder of Floobits.

About Floobits

Floobits lets you collaborate on code like you're in the same room. Think Etherpad or Google Docs, but in Sublime Text, Vim, Emacs, or IntelliJ.

If you're interested, sign up.