Skip to content

Commit def417f

Browse files
committed
Add stderr access before start
1 parent b0255e5 commit def417f

File tree

1 file changed

+16
-2
lines changed

1 file changed

+16
-2
lines changed

src/client/stdio.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { ChildProcess, IOType } from "node:child_process";
22
import spawn from "cross-spawn";
33
import process from "node:process";
4-
import { Stream } from "node:stream";
4+
import { Stream, PassThrough } from "node:stream";
55
import { ReadBuffer, serializeMessage } from "../shared/stdio.js";
66
import { Transport } from "../shared/transport.js";
77
import { JSONRPCMessage } from "../types.js";
@@ -93,13 +93,17 @@ export class StdioClientTransport implements Transport {
9393
private _abortController: AbortController = new AbortController();
9494
private _readBuffer: ReadBuffer = new ReadBuffer();
9595
private _serverParams: StdioServerParameters;
96+
private _stderrStream: PassThrough | null = null;
9697

9798
onclose?: () => void;
9899
onerror?: (error: Error) => void;
99100
onmessage?: (message: JSONRPCMessage) => void;
100101

101102
constructor(server: StdioServerParameters) {
102103
this._serverParams = server;
104+
if (server.stderr === "pipe" || server.stderr === "overlapped") {
105+
this._stderrStream = new PassThrough();
106+
}
103107
}
104108

105109
/**
@@ -158,15 +162,25 @@ export class StdioClientTransport implements Transport {
158162
this._process.stdout?.on("error", (error) => {
159163
this.onerror?.(error);
160164
});
165+
166+
if (this._stderrStream && this._process.stderr) {
167+
this._process.stderr.pipe(this._stderrStream);
168+
}
161169
});
162170
}
163171

164172
/**
165173
* The stderr stream of the child process, if `StdioServerParameters.stderr` was set to "pipe" or "overlapped".
166174
*
167-
* This is only available after the process has been started.
175+
* If stderr piping was requested, a PassThrough stream is returned _immediately_, allowing callers to
176+
* attach listeners before the start method is invoked. This prevents loss of any early
177+
* error output emitted by the child process.
168178
*/
169179
get stderr(): Stream | null {
180+
if (this._stderrStream) {
181+
return this._stderrStream;
182+
}
183+
170184
return this._process?.stderr ?? null;
171185
}
172186

0 commit comments

Comments
 (0)