Skip to content

No way to capture stderr #11

Open

Description

@Brainisthekey

Problem

_run_stream captures stderr via subprocess.PIPE but never exposes it to the caller or subclasses. The captured process.stderr and process.returncode are silently discarded.

This makes it impossible to:

  • Log diagnostic output from TF_LOG during streaming operations (plan, apply)
  • Detect and report errors that terraform/tofu writes to stderr
  • Build subclasses that add logging or monitoring without fully reimplementing _run_stream

In contrast, _run already returns a CommandResults dataclass that includes both stderr and returncode, so the pattern is established.

Proposed Solution

Store the process result on the instance after _run_stream executes, reusing the existing CommandResults dataclass. This is non-breaking — the generator API stays the same.

def _run_stream(self, args):
    args = [self.binary_path] + [str(x) for x in args]

    process = subprocess.run(
        args,
        cwd=self.cwd,
        stdout=subprocess.PIPE,
        capture_output=False,
        stderr=subprocess.PIPE,
        universal_newlines=True,
        encoding="utf-8",
        bufsize=1,
        env={
            **os.environ,
            "TF_IN_AUTOMATION": "1",
            "TF_LOG": self.log_level,
            **self.env,
        },
        timeout=None,
    )

    # NEW: store result for callers/subclasses to inspect after iteration
    self._last_stream_result = CommandResults(
        command=" ".join(args),
        stdout=process.stdout,
        stderr=process.stderr,
        returncode=process.returncode,
    )

    event_line = ""
    for buffer in process.stdout:
        if buffer == "\n":
            yield json.loads(event_line)
            event_line = ""
        else:
            event_line += buffer

Context

We use tofupy in a Celery worker that runs terraform operations. Without stderr access, we have no visibility into terraform diagnostic output, which makes debugging production issues difficult.

P.S: TF_LOG_PATH env var: tofupy already supports passing env={"TF_LOG_PATH": "/tmp/terraform.log"} to redirect terraform logs to a file. This works but requires managing temp files and reading them after each operation, which is awkward in long-running workers that want to stream logs to Python's logging in real time. And it's for debug, it anyway doesn't capture the stderr...

Activity

  1. uchime1234 commented on Sep 15, 2026

    @uchime1234

    Hi, I'd like to work on this. I'll implement the proposed solution — storing a CommandResults instance on self._last_stream_result after _run_stream finishes, mirroring what _run already does. I'll also add a test that verifies stderr and returncode are captured after streaming. Let me know if there's a preferred attribute name or if you'd rather expose it differently.

  2. uchime1234 commented on Sep 15, 2026

    @uchime1234

    Opened a PR for this: #17

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions