Breakpoints and debuggers

I’m mostly using binding.irb to explore or debug code, however, it doesn’t work with either of:

  • bin/dev
  • hanami server

This is usually caused by Puma serving multithreaded, but even when set to threads 1, 1 (and workers defaults to 0), the IRB prompt is printed, but not interactive. Maybe there’s something happening with STDIN?

It does work when using Puma directly though:

  • bundle exec puma -C config/puma.rb

Another approach is the debug gem, but I find it a bit cumbersome to get the timing right to attach. Certainly worth the hassle if the editor features a debugger, Zed unfortunately does not yet, it’s in the works though.

Still, it feels as if I’m missing something here. How do you use breakpoints when developing a Hanami app?

Use Overmind + Debug.

You can do this by first creating a Procfile.dev with the following contents:

web: bundle exec puma --config ./config/puma.rb
assets: bundle exec hanami assets compile

Then you can run Overmind to launch all processes:

overmind start --port-step 10 --procfile Procfile.dev --can-die assets,migration;

Finally, you can use overmind connect web to connect to the web process to debug and so forth. You do this by putting a binding.debug in your application code and then watching the web process hault at the breakpoint so you can connect and inspect/debug.

:light_bulb: If it helps, this is wired up for you automatically when using Hanamismith.

1 Like

Yep, +1 to @bkuhlmann suggestion of overmind.

Flexibility with process launchers is part of why the hanami dev command is just a wrapper around bin/dev. This allows you to modify bin/dev to suit your preferences.

In this case, if you know you already have overmind installed, you can change bin/dev to overmind start --procfile Procfile.dev and then hanami dev will continue to work as usual :slight_smile:

1 Like

Worth calling out here that hanami server (when hanami-reloader is installed) uses guard-puma to handle reloading itself when files change. And I think this also doesn’t work well with breakpoints that you hit directly on your web process.

To avoid this, you can run hanami server with the --no-code-reloading flag, which executes puma directly, without guard This would be the equivalent to Brooke’s suggestion of running bundle exec puma in your Procfile. Of course, by doing this you trade off the convenience of code reloading for the ability to debug inside a running web process.

I’d love it if we could find a way to support reloading and interactive debugging at the same time.

(Personally, I tend to only debug inside tests—which can also be full feature tests—which sidesteps this whole issue.)

I also use Overmind, although beware that it’s tmux-based so doesn’t work inside another tmux session. Small annoyance.

1 Like

Thanks for the Overmind hint, much better now! :smiley:

1 Like