Documentation

Requests, history and traces

Send a request from the runner, and read back every hop it made and what each service's code did with it.

The request runner

Below the canvas, with a draggable divider between them. Requests open as tabs.

A request belongs to a service. Its address is the service’s host — shown as a chip at the start of the line, and clickable to change it — followed by the path you type.

Part What it holds
The verb Click it to choose GET, POST, PUT, PATCH, DELETE, HEAD or OPTIONS.
Params The query string, as rows. Untick a param to leave it out of the URL without losing it.
Headers With Raw ticked, a text box: one header per line, and # at the start of a line to switch it off. Unticked, rows of name and value.
Body None, JSON, Text or Form (one key=value per line). JSON bodies can be re-indented and copied from the corner icons.

Send sends it, and becomes Cancel while it is in flight. Sending also saves the request, as it went — rotated values included — so a send never leaves the tab with unsaved changes. If that save fails, the tab says so; the send still goes. Save writes the request to disk without sending it.

Things to know:

  • Only to your own machine. A request’s host must be localhost or 127.0.0.1. Debugt is not a way to send requests to whatever your computer can reach.
  • Sent by the extension, not the browser, so a service does not need to allow the page’s origin, and a self-signed development certificate is accepted.
  • A service that is not up shows as a result, not an error: a refused connection or a timeout is the normal case while something is starting.
  • Cancel aborts the request upstream too, so a service is not left working on an answer nobody will read.

The response

Beside the request: the status, how long it took, its size and content type, then Body and Headers. Switch the body between Format and Raw, copy it from the corner icon, and search it with Ctrl/Cmd+F. A body over 5 MB is cut short and marked truncated.

Rotate

Some values have to change between sends: an order id, an email address. Rotate, in the body editor, changes them for you. Its cog opens a dialog where you pick a field in the body, params or headers and how it turns: Incremental, Random name, Random email, Random word or Gibberish. Tick Rotate automatically on each Send to have it happen without pressing the button.

Shortcuts

Keys Does
Ctrl/Cmd+Enter Send, or cancel a send in flight
Ctrl/Cmd+S Save the request
Ctrl/Cmd+Alt+W Close the tab
Ctrl/Cmd+F Find in a body

Saved requests

The Requests section of the left pane is a tree: a folder per service, with your own folders and requests under it.

  • Click a request to preview it; double-click to keep its tab open. Once its tab is kept open, a click goes to the tab and a double-click renames the request.
  • Right-click a folder to Add folder or Add request.
  • Right-click a request to Open, Rename, Duplicate or Delete….
  • Drag a request to move it, within the same service.
  • The filter matches request names, folders and methods.

Requests are saved as JSON files under ~/.debugt, outside your repository.

Request History

Every send is kept in the Request History section, newest first, grouped by day. Each row shows the verb and status, and the request’s name.

  • Click a row to open its trace. Double-click to rename it.
  • Right-click a row to Open in new tab, Rename, Bookmark or Move to trash, or to reach the send’s file — below.
  • Two coloured dots may follow a name: outside, for a request that did not come from the runner, and hops only, for one made with Record execution off.

A send’s file

Each send is kept as one JSON file under ~/.debugt, holding its request, response and trace. A send’s menu — on its row, in the table, and the ⋯ on its trace — offers:

  • Open in VS Code — opens the file, to read or search it in full.
  • Copy file path — where it is kept, to hand to whoever is looking into it. Hover the item to see the path.

A send that has since been dropped from history, or deleted from the trash, says its file is no longer there.

As a table

The table icon in the section’s header opens Request History as a table: filter by name, method, URL or status, and sort by any column — Status, Name, Request, When, Duration, Size or Hops.

Tick rows to select them — Shift-click selects a range — and Move to trash removes them together. Clear history moves every send to the trash except the bookmarked ones.

Bookmarks, and the limit

On the Free plan, history keeps the most recent 50 sends; the oldest goes, with its trace, as each new one comes in. Pro has no limit. A bookmarked send is kept past the limit on either plan, and past Clear history. Star a row to bookmark it.

If Pro lapses, nothing it kept is deleted: those sends stay, and only the ones made after count against the Free plan’s 50.

The trash

A send moved to the trash can be restored. Open the trash from the section’s header: Restore puts a send back, and the bin icon deletes it for good, with its request, response and trace. Auto delete after … days removes sends that have been in the trash longer than that.

Reading a trace

A send is rarely one request and one response: a service calls two others, one of those calls a third. Sending a request opens its trace over the runner, on the right of the window; the rest of the app stays live behind it. Escape closes it.

Hops

The left of the trace is the tree of hops: each request a service received, each call it made, each message it published or took off a queue. It fills in while the work is still happening.

Each row has a status — the HTTP code, or running, ok or error — the service and what was called, a bar showing when in the request it ran, and how long it took. A filled dot means that hop has a recording of the code that ran; a hollow one means it does not.

Select a hop to see, on the right, its Request and Response — headers and body — or its Message for a publish or a delivery.

Three toggles in the trace’s top bar change how the tree reads, and are also under Settings → General:

  • Show a call and the handler that answered it as one hop.
  • Leave the service name off hops under the same service.
  • Show the timeline bars.

To hide noise, click the eye icon on a hop: every hop with that label is hidden, and the Hidden menu brings them back.

Bodies are kept up to 256 KB; past that the hop says the rest was not captured.

Execution

Under the hop tree is Execution: what the selected hop’s service did in its own code while it handled the request. It is a tree of calls. Select one to see, in the order it ran:

  • its Arguments;
  • the Calls made from it;
  • the Lines run, each with the variables it changed — Values only shows just the lines that changed something, and Source shows them on the code they are from, while the service’s project is open;
  • what it Returned or Raised, last. If the recording ended before the call did, it says so there instead.

Its file and line, beside its name, open in VS Code.

This is what answers “why did it return that?” without setting a breakpoint and sending the request again.

Execution is recorded for services Debugt started, in the languages that support it: see Language support and limits. A hop that is a call out of a service has no execution of its own.

Reading a value

In Lines run, each value sits on one line. One cut off at the pane’s edge shows whole in a value bubble when you rest the pointer on it. Click it to keep the bubble open, to scroll, select from and Copy; drag its left edge to widen it. An object or array opens there on a click too, laid out one entry to a line.

In Source, a variable a line read is underlined with dots where the recording has its value. Rest the pointer on it to see the value as the line began; click to keep it open. For a line that ran more than once, the value is from the last time, and the bubble says so.

A value is recorded only so far: as deep as Value depth and as long as Value items, in Settings → Recording. Past that, a deeper part is only named — [Object], [Array] — and the rest of a list is counted. A long string, or a value past its size, is cut. When a value was not recorded whole, the bubble says which, and that Copy copies what was recorded. To have more, raise Value depth or Value items and run the service again.

Your code, not your dependencies

A recording holds the code you wrote and can read in your repository. Code that comes from a package is left out:

Language Not recorded
Node.js Anything under node_modules, and Node’s own modules
Python Anything under site-packages, dist-packages or a virtual environment (.venv, venv), and the standard library
Java Classes loaded from a jar. Only classes from a folder such as target/classes are recorded
Go The standard library and every dependency. Only your own module, or your workspace’s modules, is recorded

So when your handler calls a library — an ORM, an HTTP client, a framework’s router — the recording shows your call into it: the arguments you passed and what came back. It does not show the steps the library took inside. That keeps a recording about your logic, and keeps a framework’s thousands of internal steps from using up the step limit.

Two things follow from this:

  • Hops are different. A network call is a hop whoever makes it. A request sent by a library deep inside node_modules still appears in the tree, with what was sent and what came back — only the library’s own lines are missing from Execution.
  • “Your code” means the folder the service runs from — its launch configuration’s cwd — and everything beneath it. A file outside that folder is not recorded, which is one more reason to set cwd to the service’s own folder.

A library kept inside your repository — a vendored copy, a generated client — counts as your code. To leave such a folder out, name it in the service’s launch configuration:

"env": { "DEBUGT_EXEC_EXCLUDE": "src/vendor" }

The path is relative to cwd. Several are separated as PATH is: : on macOS and Linux, ; on Windows. This applies to Node and Python services.

When a recording is cut short

A recording stops when it reaches its limit, and says so: the step count turns red, and the tree ends with Recording stopped here — the step cap was reached. What ran after this was not recorded.

  • The Free plan records up to 5,000 steps a request, and Pro up to 200,000. A step is one call, line, return or raise in the service’s own code.
  • Raise Max steps in Settings → Recording, up to your plan’s limit.
  • Or set Max repeats per line, so a hot loop is folded into a count instead of filling the limit.

Then stop and run the service again: limits are read when a service starts.

Leaving a value out

A large or noisy value — a database connection, a framework’s request object — can be left out of recordings. Click Don’t capture beside it in a step’s details: from the next run it is shown as a one-line placeholder. The list is under Settings → Capture.

Stopping a send

While a send is in flight, or any hop of its trace is still running, the trace shows a red Stop. It aborts that request’s calls in every service it reached, and drops events still queued for it. Other requests through the same services are untouched.

Code that makes no further network call keeps running until it returns; to end that too, stop the service. Stopping reaches Node and Python services.

In its own tab

The pop-out icon opens a trace in a browser tab of its own, with the history list beside it — useful on a second screen.

Requests from outside Debugt

By default only what you send from the runner is traced. With Record requests from outside Debugt on, in Settings → Recording, a request that reaches a service from anywhere else — Postman, a browser, a phone on your network — is recorded the same way and kept in Request History, marked outside.

Every such request is kept, so add the ones you do not want — a health check, a poll — under Don’t capture hops in Settings → Capture.