Understanding lippy's errors
Good error messages are the point of lippy, not an afterthought. When something's wrong, an error tells you what happened, where, and usually what you probably meant — in plain words, never jargon. This page shows how to read them.
The shape of an error
Every error starts by saying which of two things happened:
- lippy couldn't read … — the program never ran; there's a mistake in how it's written.
- lippy stopped at line N of … — the program was running and hit something it couldn't do.
Then it shows the line, points a caret at the exact spot, explains in a sentence or two, and — when it's confident — offers a hint:
lippy stopped at line 2 of greet.lip
line 2: greeting is "hello, " + name
^
+ only works on numbers, but the left side is the string "hello, ".
To build strings, put the value inside the quotes.
hint: greeting is "hello, {name}"
A hint only appears when lippy is sure of the correction — a wrong hint is worse than none, so when it isn't confident it stays quiet.
Common mistakes, and what to write instead
Coming from another language, these are the ones you'll meet first — and lippy always suggests the fix:
| You wrote | lippy suggests |
|---|---|
= or == to compare |
equals to compare, is to assign |
is inside a condition |
drop it — comparisons work on their own |
!=, <, >, <=, >= |
not equals, less than, greater than, at most, at least |
&&, ||, ! |
and, or, not |
+ with a string |
interpolation: "hello, {name}" |
| a call inside a paren-free call | parenthesise the inner one: split trim(line) |
elif / elsif |
else if |
while |
loop with stop when |
| a misspelled name or keyword | did-you-mean the closest real one |
A few real ones
A keyword typo, caught before anything runs:
lippy couldn't read greet.lip
line 1: fnu greet(who)
^^^
lippy doesn't know the word "fnu".
hint: did you mean fun?
The = habit, in a condition:
lippy couldn't read check.lip
line 1: if guess = secret then
^
lippy doesn't use =. To compare two things, use equals.
To put a value in a name, use is.
hint: if guess equals secret then
The one trap that paren-free calls create — everything after a name belongs to it:
lippy stopped at line 1 of count.lip
line 1: total is len args + 1
^^^^^^^^
without parentheses, everything after len belongs to it — so this
asks for len(args + 1), and + only works on numbers, but args is a list.
hint: total is len(args) + 1
A misspelled name, with the fix:
lippy stopped at line 2 of tally.lip
line 2: say cuont
^^^^^
there's nothing called "cuont" here.
hint: did you mean count?
When a script stops partway
A runtime error shows the story — the line that failed, then the trail of calls that led there, written as sentences rather than a raw trace:
lippy stopped at line 3 of deploy.lip
line 3: run "rsync -a {src}/ {dst}/"
^^^
rsync finished with exit code 23 (partial transfer).
while running backup, called from line 12
while running main script
hint: to carry on when a command fails, use attempt instead of run
That last hint points at attempt — the way to let something fail without
stopping the whole script, turning the failure into a result you can check.