Debug your extension
This page covers 3 ways to find what went wrong. Step through the site's code with XDebug, watch the full output of a command or read the logs of the background processes.
Step-debug with XDebug
debug starts or restarts the webserver with XDebug on. start restarts it with XDebug off while XDEBUG is unset. The following commands turn XDebug on and off:
- Make
- Ahoy
- No wrapper
make debug # Restart with XDebug enabled
make start # Restart without XDebug
ahoy debug # Restart with XDebug enabled
ahoy start # Restart without XDebug
XDEBUG=1 vendor/bin/eddy-start # Restart with XDebug enabled
vendor/bin/eddy-start # Restart without XDebug
To step-debug the site:
- Install the XDebug PHP extension on your host, and confirm that
php -vmentionswith Xdebug. - Turn XDebug on with the preceding command marked
Restart with XDebug enabled. Confirm that theXDebugline ofinfoshowsenabled. - Start listening for debug connections in your IDE.
- Open a page of the site. The request starts a debug session in your IDE.
- When you're done, remove
XDEBUGfrom.envand your shell if you set it there. - Turn XDebug off with the preceding command marked
Restart without XDebug.
In make and Ahoy, debug has the aliases debug-on, xdebug and xdebug-on. start has the aliases debug-off and xdebug-off. debug leaves a webserver that already runs with XDebug as it is.
The server runs with xdebug.mode=debug and xdebug.start_with_request=yes, so every request starts a debug session. A browser extension that sets the XDebug trigger has no effect here. To skip debugging, stop listening in your IDE.
XDEBUG counts as unset only while it's empty or missing in your shell and in .env. Any other value turns XDebug on, 0 included. debug sets XDEBUG only for the server it starts and leaves .env as it is. When XDEBUG is set and the extension is missing, start stops with an error before it starts a server.
Code coverage stays on pcov, because the XDebug settings apply only to the webserver.
Command output
The commands print their own progress as [TASK] and [ OK ] lines. They hide the output of the tools they run, such as Composer, npm ci and Drush, until a tool fails. Then the captured output of that tool appears. The output of your project's own commands always shows: npm run build and the lifecycle scripts.
To stream the output of the tools as they run, set DEBUG=1:
- Make
- Ahoy
- No wrapper
DEBUG=1 make build
DEBUG=1 ahoy build
export DEBUG=1
vendor/bin/eddy-assemble
vendor/bin/eddy-start
vendor/bin/eddy-provision
DEBUG takes only 1, from your shell or .env, and works for every command that runs these tools. Composer and npm then stream their full output. Drush streams its progress, and the results it prints stay captured. scripts/eddy-tooling streams its Composer output too, on the runs that install the package. Without a wrapper, scripts/eddy-tooling reads DEBUG from your shell only.
Logs
The processes that keep running after a command returns write their output to the .logs directory in the project root:
| File | Written by |
|---|---|
.logs/php.log | The PHP webserver. |
.logs/chromedriver.log | The chromedriver that FunctionalJavascript tests drive. |
.logs/cloudflared.log | The public tunnel. Its process ID is in .logs/cloudflared.pid. |
With the selenium backend, the browser's output stays in its Docker container. The container is named after the WebDriver port, such as selenium-4444. To read the output, run docker logs selenium-4444, with your own port in place of 4444. info prints the port, and so does vendor/bin/eddy-info webdriver-port (see eddy-info fields). When the download of a chromedriver fails, read .chromedriver/install.log for the details.
The test runs write their reports to .logs too:
.logs/test_results/phpunit/phpunit.xml- the JUnit report of the PHPUnit run..logs/coverage/phpunitand.logs/coverage/jest- the coverage reports (see Code coverage)..logs/browser_output- the HTML pages and screenshots of Functional and FunctionalJavascript tests (see Test output). Drupal writes them tobuild/web/sites/simpletest/browser_output, andprovisionlinks that directory here.
reset removes the whole .logs directory.