on 6199865 help sign in
urbit.org/tutorials/hoon-errors.md
189 lines 6.1 kB history raw
1+++
2title = "Hoon Errors"
3weight = 12
4template = "doc.html"
5+++
7In this section we explore strategies for debugging and understanding what your
8Hoon code is doing. We cover common errors that Dojo may spit out, how to turn
9on debugging and verbose mode, and how to use debugging printfs.
11## Syntax errors
13When you get a syntax error, you'll see a message like:
15```
16syntax error at [10 12]
17```
19This is a line and column number; more exactly, the line and
20column of the first byte the parser couldn't interpret as part of
21a correct Hoon file. These values are always correct.
23Usually, the line and column tell you everything you need to
24know. But the worst-case scenario for a syntax error is that,
25somewhere above, you've confused Hoon's tall form by using the
26wrong fanout for a rune. For example, `%+` ([**cenlus**](@/docs/reference/hoon-expressions/rune/cen.md#cenlus),
27a function call whose sample is a cell) has three subhoons:
29```hoon
30%+ foo
31 bar
32baz
33```
35But if you make a mistake and write ...
37```hoon
38%+ foo
39bar
40```
42... the parser will eat the next reference below and try to treat it as a
43part of the `%+`. This can cause a cascading error somewhere
44below, usually stopped by a `==` or `--`.
46When this happens, don't panic! Binary search actually works
47quite well. Any reference can be stubbed out as `!!`. Find the
48prefix of your file that compiles, then work forward until
49the actual error appears.
51## Semantic errors
53Now your code parses but doesn't compile.
55### Turn on debugging or verbose mode
57Your first step should be to put a `!:` ("zapcol") rune at the
58top of the file. This is like calling the C compiler with `-g`;
59it tells the Hoon compiler to generate tracing references.
61Bear in mind that `!:` breaks tail-call optimization. This is a
62bug, but a relatively low-priority bug. `!.` turns off `!:`.
63Note that `!:` and `!.` are reference-level, not file-level; you can
64wrap any reference in either.
66You may also find it helpful to turn on verbose mode by entering `|verb` into Dojo, which prints (almost)
67everything happening in the kernel to the console. This is useful for performing
68stack trace. An extensive stack trace tutorial is [below](#stack-trace-tutorial).
70### Error trace
72If you have `!:` on, you'll see an error trace, like:
74```
75/~zod/home/0/gen/hello:<[7 3].[11 21]>
76/~zod/home/0/gen/hello:<[8 1].[11 21]>
77/~zod/home/0/gen/hello:<[9 1].[11 21]>
78/~zod/home/0/gen/hello:<[10 1].[11 21]>
79/~zod/home/0/gen/hello:<[11 1].[11 21]>
80/~zod/home/0/gen/hello:<[11 7].[11 21]>
81nest-fail
82```
84The bottom of this trace is the line and column of the reference which
85failed to compile, then the cause of the error (`nest-fail`).
87Hoon does not believe in inundating you with possibly irrelevant
88debugging information. Your first resort is always to just look
89at the code and try to figure out what's wrong. This practice
90strengthens your Hoon muscles.
92(Consider the opposite extreme; imagine if you had a magic bot
93that always fixed your compiler errors for you. Pro: no time
94wasted on compiler errors. Con: you never learn Hoon.)
96## Common errors
98Moral fiber is all very well and good, but sometimes you're
99stumped. Couldn't the compiler help a little? These messages do
100mean something. Here are the three most common:
102### `nest-fail`
104This is a type mismatch (`nest` is the Hoon typechecker). It
105means you tried to pound a square peg into a round hole.
107What was the peg and what was the hole? Hoon doesn't tell you by
108default, because moral fiber, and also because in too many cases
109trivial errors lead to large intimidating dumps. However, you
110can use the `~!` rune ([**sigzap**](@/docs/reference/hoon-expressions/rune/sig.md#sigzap)) to print the type of any hoon in your stack trace.
112For instance, you wrote `(foo bar)` and got a `nest-fail`. Change
113your code to be:
115```hoon
116~! bar
117~! +6.foo
118(foo bar)
119```
121You'll get the same `nest-fail`, but this will show the type of
122`bar`, then the type of the sample of the `foo` gate.
124### `find.foo`
126A `find.foo` error means limb `foo` wasn't found in the subject.
127In other words, "undeclared variable".
129The most common subspecies of `find` error is `find.$`, meaning
130the empty name `$` was not found. This often happens when you
131use a reference that does not produce a gate/mold, as a gate/mold. For
132instance, `(foo bar)` will give `find.$` if `foo` is not actually a
133function.
135### `mint-vain` and `mint-lost`
137These are errors caused by type inference in pattern matching.
138`mint-vain` means this hoon is never executed. `mint-lost` means there's a case in a `?-` ([**wuthep**](@/docs/reference/hoon-expressions/rune/wut.md#wuthep)) that isn't handled.
140## Runtime crashes
142If your code crashes at runtime or overflows the stack, you'll
143see a stack trace that looks just like the trace above. Don't
144confuse runtime crashes with compilation errors, though.
146If your code goes into an infinite loop, kill it with `ctrl-c` (you'll
147need to be developing on the local console; otherwise, the
148infinite loop will time out either too slowly or too fast). The
149stack trace will show what your code was doing when interrupted.
151The counterpart of `~!` for runtime crashes is `~|`
152([**sigbar**](@/docs/reference/hoon-expressions/rune/sig.md#sigbar)):
154```hoon
155~| foo
156(foo bar)
157```
159If `(foo bar)` crashes, the value of `foo` is printed in the
160stack trace. Otherwise, the `~|` has no effect.
162## Debugging printfs
164The worst possibility, of course, is that your code runs but does
165the wrong thing. This is relatively unusual in a typed
166functional language, but it still happens.
168`~&` ([**sigpam**](@/docs/reference/hoon-expressions/rune/sig.md#sigpam)) is Hoon's debugging printf.
169This pretty-prints its argument:
171```hoon
172~& foo
173(foo bar)
174```
176will always print `foo` every time it executes. A variant is
177`~?` ([**sigwut**](@/docs/reference/hoon-expressions/rune/sig.md#sigwut)), which prints only if a condition is
178true:
180```hoon
181~? =(37 (lent foo)) foo
182(foo bar)
183```
185For now, you need to be on the local console to see these debug
186printfs (which are implemented by interpreter hints). This is a
187bug and, like all bugs, will be fixed at some point.