Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 137 additions & 0 deletions runtime/fundamentals/debugging.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,143 @@ curl http://0.0.0.0:4507/
At this point we can introspect the contents of the request and go step-by-step
to debug the code.

## Inspecting network traffic

Starting with Deno 2.8, Chrome DevTools can inspect network traffic made by your
program in the same way it inspects traffic in a browser tab. Run your program
with `--inspect-wait` (or `--inspect` / `--inspect-brk`), open
`chrome://inspect` in a Chromium derived browser, click **Inspect** on the Deno
target, and switch to the **Network** tab.

The following built-in APIs are wired into the Network tab:

- `fetch()` — requests appear with `Type: fetch`
- `node:http` and `node:https` client requests (`http.request`, `http.get`,
`https.request`, `https.get`) — the **Type** column reflects the response
content-type (e.g. `json`, `document`), so any npm library that issues HTTP
requests through `node:http` shows up alongside `fetch()` traffic
- `WebSocket` — client connections appear alongside HTTP requests, with
handshake status and headers from the upgrade response, message frames, and a
close event when the socket is closed
- `Deno.upgradeWebSocket()` — server-side WebSocket upgrades are instrumented
too, so you can inspect both sides of a connection from a Deno-to-Deno
handshake

For each request you can see the URL, method, status code, request and response
headers, request and response bodies, and timing information.

Let's try it with a small program that uses `fetch()`:

```ts title="net.ts"
const res = await fetch("https://api.github.com/repos/denoland/deno");
console.log(res.status, (await res.json()).stargazers_count);
```

Run it with `--inspect-wait` so the program pauses until DevTools connects:

```sh
$ deno run --inspect-wait --allow-net net.ts
Debugger listening on ws://127.0.0.1:9229/...
Visit chrome://inspect to connect to the debugger.
Deno is waiting for debugger to connect.
```

Open `chrome://inspect`, click **Inspect** on the Deno target, and switch to the
**Network** tab. The `fetch()` request shows up as a regular network entry, with
the request and response panes populated:

![fetch() request in the Network tab](./images/debugger-network-fetch.png)

Click a request to see its headers, payload, response body, and timing
breakdown:

![Inspecting response headers and body](./images/debugger-network-response.png)

The same applies to `node:http` and `node:https`, so npm libraries that issue
HTTP requests through Node's built-in client (rather than `fetch()`) also show
up in the Network tab. For example:

```ts title="node-http.ts"
import https from "node:https";

const options = {
hostname: "api.github.com",
path: "/repos/denoland/deno",
headers: { "User-Agent": "deno-docs-example" },
};

https.get(options, (res) => {
let body = "";
res.on("data", (chunk) => body += chunk);
res.on(
"end",
() => console.log(res.statusCode, JSON.parse(body).stargazers_count),
);
});
```

```sh
$ deno run --inspect-wait --allow-net node-http.ts
```

The request appears in the Network tab with the same headers, body, and timing
information as a `fetch()` request — the **Type** column reflects the response
content-type (`json` for this example):

![node:https request in the Network tab](./images/debugger-network-node-http.png)

`WebSocket` connections appear in the same Network tab, with messages and the
close event surfaced as the connection progresses:

![WebSocket connection in the Network tab](./images/debugger-network-websocket.png)

Server-side WebSockets created with `Deno.upgradeWebSocket()` are also
instrumented, so you can inspect both sides of a connection — the outgoing
client `WebSocket` and the server upgrade that accepts it. For example, a small
echo server:

```ts title="ws-server.ts"
Deno.serve({ port: 8000 }, (req) => {
if (req.headers.get("upgrade") !== "websocket") {
return new Response("send a WebSocket request", { status: 426 });
}
const { socket, response } = Deno.upgradeWebSocket(req);
socket.onmessage = (e) => socket.send(`echo: ${e.data}`);
return response;
});
```

```sh
$ deno run --inspect-wait --allow-net ws-server.ts
```

After connecting DevTools and resuming execution, connect to the server from
another terminal (for example with `deno eval`):

```sh
deno eval 'const ws = new WebSocket("ws://localhost:8000");
ws.onopen = () => ws.send("hello");
ws.onmessage = (e) => { console.log(e.data); ws.close(); };'
```

The upgrade and the message frames show up in the Network tab of the server's
DevTools session:

![Deno.upgradeWebSocket() in the Network tab](./images/debugger-network-upgrade-websocket.png)

The same events are also exposed through `node:inspector` for programmatic
clients, so tooling that already speaks the Chrome DevTools Protocol against
Node can attach to Deno and observe the same network traffic without any
changes.

:::note

When no debugger is attached, the network instrumentation has effectively no
overhead — the events are only emitted while a session has opted in via
`Network.enable`.

:::

## VSCode

Deno can be debugged using VSCode. This is best done with help from the official
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.