Stop Debugging and Start Winning with Hantera's Powerful Tracing

Published on 
, by Kristoffer

There’s a specific kind of suffering that every developer knows intimately. You’re in the debugger, stepping through the code, getting closer to the problem. One more step. One more. And then — you pressed F10 one too many times. The state you needed is gone. The function returned. The moment passed.

Now you have to start over.

If you have a tidy unit test that reproduces it, fine. Hit run, set your breakpoints, go again. But in the real world, “starting over” often means rebuilding a very specific state in the system. A particular sequence of events had to happen first. A live webhook needs to fire. The bug only shows up on the third run because of some timing issue you haven’t fully understood yet.

So you set everything up again. Trigger the thing again. Step through again. And if you’re unlucky, you blink at the wrong moment and miss it. Again.

This loop can eat hours. On a bad day, days. The cruel part is that the harder the bug, the more elaborate the setup — and the more demoralizing it is to rebuild from scratch every time you overshoot.

Debugging Arrives Late to the Scene

Classic debugging is a “freeze time at one moment” activity. You stop the world, look around, and unpause. The past is gone. You can only see what’s in front of you right now.

This works fine for simple bugs in isolated code. But modern applications are not simple or isolated. Business logic runs in response to events. Multiple components interact. A reactor triggers because a job ran, which was scheduled by a rule that responded to an event three steps ago.

By the time you’ve paused at the interesting line, the whole story of how you got there has already happened and vanished. You’re arriving at the crime scene hours after the fact, and the witnesses have all gone home.

Running Once and Keeping Everything

A tracer works differently. It watches the program run without stopping it. Every step of the evaluation, every function call, every value — all of it gets recorded as the program executes normally.

You run your test case once. The tracer has captured the complete history of every step across every component that executed. Now you can navigate that history at your leisure. Forward, backward, jump to any step. The bug didn’t disappear when you stepped past it, because you were never stepping live. You’re reading a recording.

I remember the first time I really internalized this shift. I’d spent most of an afternoon bouncing between breakpoints trying to figure out why a calculated value came out wrong. Set up the state, trigger the flow, step through, overshoot, start over. Four times. On the fifth attempt I finally saw it — a lookup returning nothing instead of a default. Twenty seconds of insight, three hours of ceremony.

With tracing, that entire afternoon collapses to a few minutes. You run it once. You open the trace. You navigate to the wrong value and work backwards until you see where it came from.

The Visibility You Didn’t Know You Were Missing

Tracing gives you something beyond fixing the bug in front of you. When you can see which parts of your code actually ran, and how many times each part ran, you start noticing things you never would have caught with a breakpoint.

A heat map of execution frequency is a surprisingly useful artifact. That block you assumed ran once? It ran seventeen times. That branch you thought was always taken? It never fired at all during this particular flow. Performance issues surface this way. So do correctness issues — places where your code is quietly doing something different from what your mental model said it should.

Webhooks, and Why This Is Especially Valuable There

One of the more painful areas to debug in any platform is incoming webhooks. The external system fires the event once. You either caught it or you didn’t. Miss it, and you need to go back to the external system, find the replay mechanism if one exists, hope the payload is still the same, and start over.

When your dev tooling captures the full request and response automatically, this stops being a problem. The webhook was already recorded. The request body, the headers, the response — all of it is right there. Replay it whenever you want, as many times as you want. It’s just an HTTP request at that point.

What the Dev Loop Actually Looks Like Now

In Hantera’s dev mode, evaluation tracing integrates directly into the CLI. Spin up dev mode with the trace flag, and every component that executes — reactors, rules, promotions — gets captured automatically and streamed to your local machine.

From there, the VS Code extension for Hantera lets you open any trace entry and walk through the full execution tree. Filter by code location: put your cursor anywhere in a Filtrera script and see every step that passed through that line. Toggle a heat map to see execution frequency at a glance.

The workflow becomes: run your scenario once, then spend as much time as you need exploring what happened. No rebuilding state. No rerunning the app. No hoping you catch it this time.

What used to take hours now takes minutes. See it in action on our YouTube Channel