Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Debugging Erlang code can be tricky at times, especially dealing with <code>badmatch</code> errors. In general, two good guidelines to keep are:</p> <ul> <li>Keep functions short</li> <li>Use return values directly if you can, instead of binding temporary variables (this will give you the benefit of getting <code>function_clause</code> errors etc which are way more informative)</li> </ul> <p>That being said, using the debuggers are usually required to quickly get to the bottom of errors. I recommend to use the command line debugger, <code>dbg</code>, instead of the graphical one, <code>debugger</code> (it's way faster when you know how to use it, and you don't have to context switch from the Erlang shell to a GUI).</p> <p>Given the sample expression you provided, the case is often that you have more than just variables being assigned to other variables (which is absolutely unnecessary in Erlang):</p> <pre><code>run(X, Y) -&gt; X = something(whatever), Y = other:do(more_data), </code></pre> <p>Debugging a <code>badmatch</code> error here is aided by using the command line debugger:</p> <pre><code>1&gt; dbg:tracer(). % Start the CLI debugger {ok,&lt;0.55.0&gt;} 2&gt; dbg:p(all, c). % Trace all processes, only calls {ok,[{matched,nonode@nohost,29}]} 3&gt; dbg:tpl(my_module, something, x). % tpl = trace local functions as well {ok,[{matched,nonode@nohost,1},{saved,x}]} 4&gt; dbg:tp(other, do, x). % tp = trace exported functions {ok,[{matched,nonode@nohost,1},{saved,x}]} 5&gt; dbg:tp(my_module, run, x). % x means print exceptions {ok,[{matched,nonode@nohost,1},{saved,x}]} % (and normal return values) </code></pre> <p>Look for <code>{matched,_,1}</code> in the return value... if this would have been <code>0</code> instead of <code>1</code> (or more) that would have meant that no functions matched the pattern. Full documentation for the <code>dbg</code> module can be found <a href="http://erldocs.com/R14B03/runtime_tools/dbg.html" rel="noreferrer">here</a>.</p> <p>Given that both <code>something/1</code> and <code>other:do/1</code> always returns ok, the following could happen:</p> <pre><code>6&gt; my_module:run(ok, ok). (&lt;0.72.0&gt;) call my_module:run(ok,ok) (&lt;0.72.0&gt;) call my_module:something(whatever) (&lt;0.72.0&gt;) returned from my_module:something/1 -&gt; ok (&lt;0.72.0&gt;) call other:do(more_data) (&lt;0.72.0&gt;) returned from other:do/1 -&gt; ok (&lt;0.72.0&gt;) returned from my_module:run/2 -&gt; ok ok </code></pre> <p>Here we can see the whole call procedure, and what return values were given. If we call it with something we know will fail:</p> <pre><code>7&gt; my_module:run(error, error). ** exception error: no match of right hand side value ok (&lt;0.72.0&gt;) call my_module:run(error,error) (&lt;0.72.0&gt;) call my_module:something(whatever) (&lt;0.72.0&gt;) returned from my_module:something/1 -&gt; ok (&lt;0.72.0&gt;) exception_from {my_module,run,2} {error,{badmatch,ok}} </code></pre> <p>Here we can see that we got a <code>badmatch</code> exception, <code>something/1</code> was called, but never <code>other:do/1</code> so we can deduce that the badmatch happened before that call.</p> <p>Getting proficient with the command line debugger will save you a lot of time, wether you debug simple (but tricky!) <code>badmatch</code> errors or something much more complex.</p> <p>Hopefully, all this will be easier when Erlang R15 comes out with line numbers in exceptions!</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload