5th
Testing / Mochiweb / Stacktraces
So, I’m somewhat test-obsessed (because I accept my own prediliction for making dumb mistakes over and over, and I like having the computer keep an eye out for me. Also, it makes programming a lot more fun).
With a mochiweb app, for certain kinds of testing, I want to launch an instance of my mw server, hit it with an http request, and check the responses. Fortunately, Erlang’s lightweight processes make this very easy. Unfortunately, when I kept things simple, I wasn’t seeing any stack traces when the mw server failed—the outer process, which had launched the mw server under test, would just get a crypic connection closed message, and that was it. And, ‘cause I do like to test as I go, I see failures all the time.
I asked on the mw list about this, and someone suggested starting erlang with -boot sasl, which gives it the OTP infrastructure, which does capture stack traces. But it also produces an incredibly verbose output, making the stack trace very hard to find. And, I couldn’t figure out how to get Emacs, which has a fantastic Erlang compile/shell feature, to launch erlang with -boot sasl.
I was beginning to think of really complex solutions involving somehow attaching the shell to the server process, when I suddenly realized there was a simple solution I was missing: I could just wrap my server handler in a catch, use eunit’s debugFmt to print out the stack trace, and I’d be all set. And it worked beautifully. Here’s the code. In my test function, I took:
RotatorHandler =
fun (Req) ->
handle_rotator(Req, {RuleUrlTmpl, ProfileUrlTmpl})
end,
And changed it to:
RotatorHandler =
fun (Req) ->
try
handle_rotator(Req, {RuleUrlTmpl, ProfileUrlTmpl})
catch Class:Exception ->
?debugFmt("~p", [[{Class,Exception} |erlang:get_stacktrace()]]),
throw({Class,Exception})
end
end,
And now it produces a simple stack trace on failure. Woo, woo!
-Dan M

