The rule was meant to be strict.
Payments service.
Any error at all,
page someone.
So the threshold
in the config
was zero.
Not one.
Zero.
For a month
the pager stayed quiet,
and everybody took that
as good news.
Then a customer wrote in.
Four card payments
had failed that Tuesday,
one after another,
and nobody had looked.
The alert rule was fine.
The config was fine.
The line that read the config
was this.
const threshold = rule.threshold || 5;
Somebody had added a default,
sensibly,
for rules that did not set one.
Here is what the two bars
actually mean.
Return the left side
if it is truthy.
Otherwise
return the right side.
And in JavaScript
zero is not truthy.
Neither is an empty string,
or NaN,
or false.
So || cannot tell
you did not tell me
from you told me zero.
Both become five.
Four failures
stayed under five.
The pager did exactly
what the code asked.
Since 2020
the language has had
the operator this line wanted.
Two question marks.
rule.threshold ?? 5
It falls back only
when the left side
is null or undefined.
Missing.
Not small,
not empty,
not false.
Zero stays zero.
There is a version
for assignment as well.
options.timeout ??= 30000
The same trap
waits in other places.
timeout || 30000
turns no timeout,
written as zero,
into thirty seconds.
name || "Anonymous"
erases a name
somebody cleared on purpose.
enabled || true
is always true,
whatever the user chose.
Python's or
does exactly the same thing,
for the same reason.
Default parameters
in a JavaScript function
are stricter.
They only fill in
when the argument is undefined.
Pass null
and you keep null.
So search your code
for || followed by a number,
a string,
or true.
For each one,
ask a single question.
Is zero,
or empty,
a value somebody might mean?
If yes,
it wants ??.
Then test the default
the way it failed.
Not a rule
with no threshold.
A rule
with a threshold of zero.
Zero is a number.
Your fallback
should only answer
when nobody did.
– Serguey Asael Shinder
Top comments (0)