Debugging Dart Hooks

When a build[^1] hook isn‘t working as expected, you can investigate the intermediate files generated by the Dart and Flutter SDK build process. These files provide insight into the inputs, outputs, and any errors that occurred during the hook’s execution.

Key Debugging Directory

All debugging artifacts are stored within the .dart_tool directory of your project. The hook runner generates a unique folder for each hook execution, containing temporary and output files.

You can find the most important debugging files in a subdirectory specific to your hook's execution. The path is of the form .dart_tool/hooks_runner/<package_name>/<some_hash>/, where <package_name> is the name of the package containing the hook. For example, for a hook in a package named sqlite, it would be .dart_tool/hooks_runner/sqlite/221e109fbc/.

When you run a build, hooks for all dependencies are executed, so you might see multiple package directories.

The <some_hash> is a checksum of the hook‘s configuration. If you are unsure which hash directory to inspect within your package’s hook directory, you can delete the .dart_tool/hooks_runner/<package_name>/ directory and re-run the command that failed. The newly created directory will be for the latest invocation.

Inside this directory, you will find:

  • input.json: Contains the exact configuration and data passed into your build hook. Reviewing this helps confirm if the hook is receiving the expected build configuration.
  • output.json: This file stores the JSON data that your build hook produced as its result.
  • stdout.txt: Captures any standard output from your build hook. This is where messages from a logger or print statements will appear.
  • stderr.txt: Captures any error messages or exceptions thrown during the hook's execution.

Using a Debugger

To step through your code with a debugger, run the build hook from its source file and provide the input.json via the --config flag. This allows you to set breakpoints in your IDE and inspect the hook's execution.

For example:

dart run hook/build.dart --config .dart_tool/hooks_runner/your_package_name/some_hash/input.json

Make sure to replace hook/build.dart, your_package_name, and some_hash with the actual paths from your project.

VS Code Launch Configuration

To debug in VS Code, you can create a launch.json file in a .vscode directory in your project root. This allows you to run your hook with a debugger attached.

Here is an example configuration:

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Debug Hook",
      "type": "dart",
      "request": "launch",
      "program": "path/to/your/hook/build.dart",
      "args": [
        "--config",
        ".dart_tool/hooks_runner/your_package_name/some_hash/input.json"
      ]
    }
  ]
}

Again, make sure to replace path/to/your/hook/build.dart, your_package_name, and some_hash with the actual paths from your project. After setting this up, you can run the “Debug Hook” configuration from the “Run and Debug” view in VS Code.

[^1]: This debugging strategy also works for other hooks than build hooks, but this documentation focuses specifically on build hooks.