The Arsenic Poison in My Environment
It was the fourth day in my new office. My co-workers had already fix some bugs and add new features to our platform. Everyone celebrated their achievement while happily enjoying their lunch and coffee.
I was among those happy people, sit on my desk, while glaring the lifeless monitor. Wondering, why my life is so f*cked up.
Oh, yes, I’m a proud engineer. And the fact that sometime I made mistakes hurts my ego so much. Thus, for the sake of my pride, whenever I found any bug in my code, I will fix it with all cost. Sometime I even let myself consumed by the darkness just to see my code run again.
However, this bug is different. It is not the kind of bug that you can solve by googling or asking question on stack-overflow. And probably this is not even a bug, considering I didn’t write any code yet. I have just copy-pasted .env
from my co-worker and try to run one of our micro-services.
I can’t show you the original .env
file or the original micro-service, but I can tell you what happened.
Honey vs Poison
To show you what happened, I made a Node.Js script named index.js
. This script do a very trivial things:
- Read
SERVICE
andPORT
from the environment - If
SERVICE
is “mysql” andPORT
is “3306”, print “Nice !!!” to the screen. - Otherwise print “Bad :(” and show how sad we are.
I also made two env
file. The first one named honey.env
, while the second one named poison.env
. Both declaring the same thing. The SERVICE
should be “mysql” and the PORT
should be “3306”.
According to my common sense, the script should show the same result, either you pass honey.env
or poison.env
.
But as you see at the terminals:
source honey.env && node index.js
give you “Nice !!!”- while
source poison.env && node index.js
give you “Bad :(”
For the sake of Zeus, Poseidon, and Hades, what the hell is happening here?
Real Coder Never Give Up…
Day after day, I kept trying to do the same thing with different approaches. I tried to remove and rebuild my docker containers. I edit the .env
several times. Add double quotes and single quotes. Remove libmysql-dev, install it again, downgrade Node.Js, remove node_modules and performing npm install
. Delete the repository, clone it again, use vim
instead of vscode
, and back to vscode
again…
But at the end, it just didn’t work. Everything is damn correct. I can’t see anything wrong here. Should I restart my computer again? Should I install new operating system? Should I buy a new laptop? Or should I just give up being a software developer?
So I close my eyes for a little while. Wrap myself in the gentle darkness. I’ve lost some of the things so far I’ve trusted: Javascript interpreter.
The Eyes of Truth
After fighting an endless battle with no result, one of my senior co-worker suddenly come with a very brilliant idea. He sit at my desk, cast some magical spell, to unveil the truth…
Again, I can’t show you what he typed, but I can tell you what happened:
Yes, he just add one single line to reveal everything: console.log
. Now, I can clearly see that there is a \r
in my poison.env
. And as expected, 'mysql\r' !== 'mysql'
.
The Arsenic Poison named CRLF
In our office, we use slack
for communication. I don’t know what happened, but apparently when I copy pasted a snippet from slack
, the line-ending character was altered (Actually I’m not sure about this).
In windows, the default eol
is \r\n
. While in Linux and mac, the default eol
is just \n.
\r
is known as CR
or Carriage Return
, while \n
is known as LF
or Line Feed
. So, windows use CRLF
, while everything else use LF
.
The funny thing here is: my coworkers use mac
, while I use ubuntu
. No one use windows except our managers. This is why, I think slack
is the culprit…
Whatever. This CRLF
thing might sound funny once you see what happened. But this can also be frustrating…
CRLF
is like arsen. A very poisonous metal that has no taste or odor. Luckily it’s not really killing you, and everything that is not killing you, make you stronger…
What We Can Do?
Next time you work with env
file with vscode
, keep your eyes open, see at the bottom panel, make sure it is LF
, not CRLF
.