loading...

External dependencies which read and act on environment variables?

ben profile image Ben Halpern Updated on ・1 min read

We recently had an issue where a Ruby gem that was part of our project was taking action based on the value of an environment variable. This behavior was not mentioned anywhere in the documentation and completely tripped us up.

The behavior difference was subtle and totally silent.

At best the library was expecting us to follow an implied convention they were dictating, at worst it was a disaster waiting to happen.

Or is this a failure to exercise our code extensively enough and modify environment variables with more care? How would you guard against this sort of issue?

Discussion

markdown guide
 

I guess that if it's not mentioned in the documentation then that's Problem Number One.

It's difficult to judge without more information, but it seems that if you did know that this was critical then it would be possible to code up something in an initialiser to warn you of changes. Message to Slack?

 

First of all, every behavior of a library one is releasing to the public should be documented; failing that simple requirement, I would say your dependency was unfit for public distribution.

Also, environment variables are pretty common in most projects, so one has to be careful to avoid naming conflicts. It should be best practice to have a namespace for your environment variables, e.g. if your project is called foo, prefix them with FOO_NAME instead of just going with NAME.

 

I disagree -- getting configuration from the environment is like getting it from the registry in Windows. It makes sense for engines (Node), databases, web servers, and other system level software your average library or application developer installs separately rather than what their code depends on. Utility libraries have no business looking to the environment; that's what config files are for. The environment can change independently and with no warning, but a reserved file that has to be at least copied and pasted in is much more closely linked to the running code.

 

I really like that wrapper script idea. Gonna put that in my toolbox for when I need it.

I agree that code that polls environment vars is old-school UNIX stuff that you just kind of get used to when you've been working on UNIX/Linux long enough. But I still think it's terrible. It's a global var, with all the problems that come with that.

I love the idea of a wrapper script to encapsulate and enumerate all the environmental settings for an application. It gives maintainers a chance to see what's needed, see comments about how it's used or why it's there, etc.

I'd say Rails is a framework; a gem you're including in your Rails app is a utility library. It's "what your code runs on" vs "what it uses". You'd expect Rails to be an external system with external means of configuration; most people would not expect a database driver or webapp middleware to use configuration their application doesn't supply on its own.

 

...is the scariest sentence I've read all day.