This project is archived. Its data is read-only. This project is read-only.
When target process fails, `meltano elt` may report `ConnectionResetError` or `BrokenPipeError` error instead of loader failure
As reported by @cooley1 [on Slack](https://meltano.slack.com/archives/CFG3C3C66/p1611076265035100?thread_ts=1610560265.206500&cid=CFG3C3C66): When the target process dies (because of an error or being killed by the OS) and its stdin stream is closed, the [`capture_subprocess_output(p_tap.stdout, p_target.stdin)`](https://gitlab.com/meltano/meltano/-/blob/91bdd3d7e7c6b8e8965cbed91aa16cce0ac6ec77/src/meltano/core/runner/singer.py#L119) call that's responsible for forwarding tap output to the target may encounter a `BrokenPipeError` in [`writer.write(line)`](https://gitlab.com/meltano/meltano/-/blob/91bdd3d7e7c6b8e8965cbed91aa16cce0ac6ec77/src/meltano/core/logging/utils.py#L71) or a `ConnectionResetError` in [`await writer.drain()`](https://gitlab.com/meltano/meltano/-/blob/91bdd3d7e7c6b8e8965cbed91aa16cce0ac6ec77/src/meltano/core/logging/utils.py#L72) _before_ [`p_target.wait()`](https://gitlab.com/meltano/meltano/-/blob/91bdd3d7e7c6b8e8965cbed91aa16cce0ac6ec77/src/meltano/core/runner/singer.py#L139) realizes that the target has quit, resulting in the [exception being re-raised](https://gitlab.com/meltano/meltano/-/blob/91bdd3d7e7c6b8e8965cbed91aa16cce0ac6ec77/src/meltano/core/runner/singer.py#L178) immediately and reported to the user, instead of the [target's remaining output being processed](https://gitlab.com/meltano/meltano/-/blob/91bdd3d7e7c6b8e8965cbed91aa16cce0ac6ec77/src/meltano/core/runner/singer.py#L204) and the [target's failure being reported](https://gitlab.com/meltano/meltano/-/blob/91bdd3d7e7c6b8e8965cbed91aa16cce0ac6ec77/src/meltano/core/runner/singer.py#L229) as the reason `meltano elt` failed. `capture_subprocess_output` may need to rescue these `ConnectionResetError` or `BrokenPipeError` errors and finish silently, so that `p_target.wait()` gets a chance to realize that the process died, which we would then handle as appropriate. Alternatively, we could explicitly detect when `capture_subprocess_output(p_tap.stdout, p_target.stdin)` raises `ConnectionResetError` or `BrokenPipeError`, deduce that this means that `p_target.stdin` is closed, and handle this just like we would `p_target` dying.
issue