The Feed Doctor Foils…Himself

May 24, 2013

Digital Marketing ChannelAdvisor By ChannelAdvisor

Today I was
helping out some of my colleagues with a very clever, but tricky, rule. We were
using classification name (or “class”) to map to Amazon browse nodes. We had
decided to manage the maps in several lookup lists: one for each class…almost. Each
of these lists maps some keyword (which is found in the product title) to an
Amazon browse node. Here’s a first pass at the rule:

LOOKUP($itemclassificationname,$itemtitle,”partial”)

There’s just
one problem: we don’t have lists for some of the classes, so this lookup will
give us an error for those classes, since we’re trying to do a lookup in a list
that doesn’t exist. No problem: we can make a “master list” of classes that
have a list, then check the master list, and if the class was in that list,
then we do the lookup. Otherwise, we’ll output a default value. Here’s the
updated rule:

IF(ISINLIST(“Master List”,$itemclassificationname),
LOOKUP($itemclassificationname,$itemtitle,”partial”), “Default”)

Let’s say we
have three classes: Shirts, Shoes, and Shorts. We have lookup lists named
“Shirts” and “Shoes” (otherwise, we’d get no service, right?), but not one
named Shorts. The master list then contains two entries: Shirts and Shoes. When
this rule runs for products in the Shirts and Shorts classes, the ISINLIST
returns true, and we do the lookup. We’d expect for products in the Shorts
class that the ISINLIST returns false, and we get the Default value.

There’s just
one problem: when I ran this rule for products in class “Shorts,” I got an
error: “No list named ‘Shorts.’”

What
happened? The ISINLIST was false, so we should have gotten the Default value.
It turns out I forgot one of the little idiosyncrasies of the business rule
engine: every function gets evaluated;
in programmer-speak, we say that all the “code paths” are executed. That means
that even though the ISINLIST was false, we still
did the LOOKUP, even though its output was ignored. And so, the LOOKUP happened
for a list, “Shorts” that didn’t exist…and gave us an error.

It took me
several frustrating, hair-pulling minutes to figure this out. The fix was easy,
though: turn the rule inside-out! That is, I just put the IF inside the LOOKUP, like this:

LOOKUP(IF(ISINLIST(“Master
List”,$itemclassificationname),$itemclassificationname,”Dummy
List”),$itemtitle,”partial”))

Notice that
if the class is NOT in the master list, we lookup the title in the “Dummy
List.” And this is a new list I made that has pretty much nothing in it…but it
IS a list that exists.

Because
these kinds of errors can be tricky to figure out, a lot of our functions are
very forgiving with their input, and instead of errors just give you blanks.
This is sometimes called a “silent failure,” and they’re not always
appropriate. But in this case, I was wishing I had made this failure a silent one.
There are some other functions that don’t
fail silently. Besides the list-related ones, the most common culprits are the date-related
functions (such as ADDTODATE).

So to sum
up: the next time your business rule gives you an error you can’t figure out, maybe
it’s a “code path” you thought the rule wouldn’t take, and try fixing it by
turning your IF statement inside-out.

Post by Anthony Alford, Technical Lead at ChannelAdvisor.