DEV Community

Achille Lacoin
Achille Lacoin

Posted on

How to debug Bubble Tea applications in Visual Studio Code

The problem

I've been working on a new TUI for a few weeks using the Bubble Tea framework.

I currently use VS Code as my main IDE, coupled with the GO extension. Among other features, this extension gives you the ability to debug golang extensions thanks to dlv.

However, if you try to debug a Bubble Tea application using the default config, your TUI will never start and you will see the following error in your debug console : Error: open /dev/tty: device not configured.

// The default config is not useful for debugging TUIs
{
    "configurations": [
        {
            "name": "Launch Package",
            "type": "go",
            "request": "launch",
            "mode": "auto",
            "program": "${fileDirname}"
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

Fixing the problem

The Bubble Tea README mention that in order to fix the issue, you need to run the debugger in headless mode.

# Start the debugger
$ dlv debug --headless .
API server listening at: 127.0.0.1:34241

# Connect to it from another terminal
$ dlv connect 127.0.0.1:34241
Enter fullscreen mode Exit fullscreen mode

So in order to attach the VS Code debugger to a bubble tea application, you will need to:

  1. Launch the debugger in headless mode:

    dlv debug --headless --listen=:2345 .
    
  2. Connect to it from vscode

    // .vscode/tasks.json
    {
        "configurations": [
            {
                "name": "Attach to Sunbeam",
                "type": "go",
                "debugAdapter": "dlv-dap",
                "request": "attach",
                "mode": "remote",
                "remotePath": "${workspaceFolder}",
                "port": 2345,
                "host": "127.0.0.1"
            }
        ]
    }
    

Optional: Automatically start the debugger

The method above still requires two actions each time you want to debug your applications. Fortunately, you can setup a preLaunchTask that will be run each time you start debugging your application.

We will create a background task that will be responsible for starting the dlv headless server. In order to allow VS Code to dectect wether the server started successfully or returned an error, we need to define a problemMatcher:

// .vscode/tasks.json
{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "Run headless dlv",
            "type": "process",
            "command": [
                "dlv",
            ],
            "args": [
                "debug",
                "--headless",
                "--listen=:2345",
                "--api-version=2",
                "${workspaceFolder}/main.go"
            ],
            "isBackground": true,
            "problemMatcher": {
                "owner": "go",
                "fileLocation": "relative",
                "pattern": {
                    "regexp": "^couldn't start listener:", // error if matched
                },
                "background": {
                    "activeOnStart": true,
                    "beginsPattern": "^API server listening at:",
                    "endsPattern": "^Got a connection, launched process" // success if matched
                }
            }
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

Then, we'll reference this preLaunchTask in our debugger config:

{
    "configurations": [
        {
            "name": "Attach to Sunbeam",
            "type": "go",
            "debugAdapter": "dlv-dap",
            "request": "attach",
            "mode": "remote",
            "remotePath": "${workspaceFolder}",
            "port": 2345,
            "host": "127.0.0.1",
            "preLaunchTask": "Run headless dlv" // Here !
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

Congrats, you should now be able to setup breakpoints and debug your bubbletea application from VS Code!

Thanks for reading ! And if you want to checkout what I'm working on, please take a look at the sunbeam repository.

Top comments (1)

Collapse
 
kevm profile image
Kevin Miller • Edited

I used this post to get my VSCode F5 debugging setup but later ran into a problem where I could not figure out how to pass arguments to the cli application I was debugging. Turns out you need to make the final tasks.json args entry -- and then tack on your cli arguments.

"args": [
    "debug",
    "--headless",
    "--listen=:2345",
    "--api-version=2",
    "${workspaceFolder}/cmd/cli",
    "--",
    "arg1=true",
    "-h=example.com"
],
Enter fullscreen mode Exit fullscreen mode