Vscode Debugging
Install debugpy
poetry add debugpy
VScode launch.json file
The
launch.json
file in Visual Studio Code (VS Code) is part of its debugging configuration. It allows you to define how your project or application should be launched and debugged. Below is everything you need to know about thelaunch.json
file, including its structure, key fields, and advanced configurations.
What is launch.json
?
- A configuration file used by VS Code to define debugging settings.
- It resides in the
.vscode
folder in your project directory. - It supports multiple configurations for debugging different scenarios (e.g., running a script, attaching to a remote debugger, or debugging tests).
Location of launch.json
- Located in
.vscode/launch.json
in your project directory. - If it doesn’t exist, VS Code will prompt you to create one when you click the “Run and Debug” sidebar and select “Create a launch.json file.”
Structure of launch.json
A launch.json
file consists of an array of configurations:
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch Script",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/script.py",
"console": "integratedTerminal"
}
]
}
version
: Specifies the version of the debugging schema. Use0.2.0
.configurations
: An array of objects, each defining a specific debugging scenario.
Key Fields in launch.json
General Fields
name
: The display name of the configuration in the Run and Debug dropdown.type
: The debugger type (e.g.,python
,node
,java
, etc.).request
:launch
: Starts the program or application.attach
: Attaches to a running process for debugging.
program
: The entry point of your application (e.g., a script path).args
: Arguments to pass to the program.console
:integratedTerminal
: Use VS Code’s built-in terminal.externalTerminal
: Use an external terminal.
Python-Specific Fields
pythonPath
: Path to the Python interpreter. If omitted, VS Code uses the Python interpreter set in the workspace.django
: Set totrue
to enable Django debugging.justMyCode
: Set tofalse
to step into library code during debugging.
Remote Debugging
host
: The remote machine’s hostname or IP address.port
: The port to connect to (e.g., fordebugpy
).pathMappings
: Maps local and remote file paths for remote debugging.
Environment Variables
env
: Defines environment variables for the debug session.envFile
: Path to a.env
file containing environment variables.
Advanced Debugging
stopOnEntry
: Stops execution at the entry point of the program.logToFile
: Saves debugger logs to a file.cwd
: Sets the working directory of the application.
Common Configurations
1. Run a Python Script
{
"name": "Run Script",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/script.py",
"console": "integratedTerminal"
}
2. Debug Django
{
"name": "Django Debug",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/manage.py",
"args": ["runserver", "--noreload"],
"django": true,
"env": {
"DEBUG": "1"
},
"console": "integratedTerminal"
}
3. Attach to Debugpy
{
"name": "Attach to Debugpy",
"type": "python",
"request": "attach",
"host": "localhost",
"port": 5678,
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
"remoteRoot": "${workspaceFolder}"
}
]
}
4. Run Tests
{
"name": "Run Tests",
"type": "python",
"request": "test",
"console": "integratedTerminal",
"justMyCode": true
}
5. Debug Flask
{
"name": "Flask Debug",
"type": "python",
"request": "launch",
"module": "flask",
"env": {
"FLASK_APP": "app.py",
"FLASK_ENV": "development"
},
"args": ["run"],
"console": "integratedTerminal"
}
6. Node.js Application
{
"name": "Node.js Debug",
"type": "node",
"request": "launch",
"program": "${workspaceFolder}/app.js"
}
Path Variables in launch.json
${workspaceFolder}
: Path to the root folder of your workspace.${file}
: Path to the currently open file.${relativeFile}
: Relative path of the open file.${cwd}
: Current working directory.
Environment Variables in launch.json
Inline Environment Variables
"env": {
"DEBUG": "true",
"API_KEY": "12345"
}
Use an .env
File
"envFile": "${workspaceFolder}/.env"
.env
file example:
DEBUG=true
API_KEY=12345
Debugging Scenarios
Remote Debugging
To debug a process running on a remote server: 1. Run debugpy
or equivalent on the server, exposing a port (e.g., 5678
). 2. Use an attach
configuration in launch.json
with the server’s IP and port.
Debugging Docker
- Expose the debug port in your Docker container.
- Map local paths to container paths using
pathMappings
.
Conditional Debugging
Use conditions to enable debugging only for specific scenarios:
"condition": "process.env.DEBUG === 'true'"
Common Issues and Solutions
- Breakpoints Not Hit
- Ensure the debugger is attached correctly.
- Verify file paths in
pathMappings
.
- Port Conflicts
- Change the debug port if another process uses it.
- Debugger Not Attaching
- Ensure the
debugpy
or equivalent is listening on the expected port. - Check firewall settings for remote debugging.
- Ensure the
- Library Code Not Stepped Into
- Set
"justMyCode": false
to debug library code.
- Set
Best Practices
Use Descriptive Names Use meaningful names for configurations to identify them quickly.
Organize Configurations Group related configurations together, such as separate entries for running tests, debugging the server, or attaching to remote processes.
Environment-Specific Settings Use different configurations for development, staging, and production environments.