@@ -23,15 +23,11 @@ import type { ProxyInitProgress } from '../../utils/error-messages.js';
2323import { getErrorMessage , SessionNotFoundError } from '../../errors/debug-errors.js' ;
2424import { proxyLogPathFor } from '../../proxy/session-log-layout.js' ;
2525
26- /** How many trailing proxy-log lines are worth reading after a failure. */
26+ /** How many trailing proxy-log lines are worth reporting after a failure. */
2727const PROXY_LOG_TAIL_LINES = 80 ;
2828
29- /**
30- * Character cap on the tail. Generous on purpose: it exists so a proxy log with
31- * one pathological multi-megabyte line cannot blow up the record, not to trim a
32- * normal 80-line tail, which is a few kilobytes.
33- */
34- const PROXY_LOG_TAIL_CHARS = 64 * 1024 ;
29+ /** Hard I/O and allocation cap applied before the log is sanitized. */
30+ export const PROXY_LOG_TAIL_MAX_BYTES = 64 * 1024 ;
3531
3632 /** The pointers a failed launch/attach returns to the caller (issue #493 / #551). */
3733 export interface ProxyFailureDiagnostics {
@@ -45,7 +41,7 @@ const PROXY_LOG_TAIL_CHARS = 64 * 1024;
4541 */
4642export interface ProxyFailureLogDeps {
4743 logger : ILogger ;
48- fileSystem : Pick < IFileSystem , 'readFile ' > ;
44+ fileSystem : Pick < IFileSystem , 'readTail ' > ;
4945}
5046
5147/** The two operations that can fail this way, named as they appear in the log. */
@@ -94,7 +90,7 @@ export function collectProxyFailureDiagnostics(
9490/**
9591 * Read the last `tailLineCount` lines of the proxy log, if there is one.
9692 *
97- * Reads straight through rather than asking `pathExists` first: the proxy is
93+ * Reads the bounded tail rather than asking `pathExists` first: the proxy is
9894 * still writing (and may rotate) this file, so an exists-then-read pair can
9995 * report "no log" for a file that appeared a millisecond later, and spends a
10096 * second syscall to do it. `ENOENT` — the answer that check was buying — is
@@ -111,18 +107,18 @@ export function collectProxyFailureDiagnostics(
111107 * error that sent us here still reaches the log intact.
112108 */
113109export async function readProxyLogTail (
114- fileSystem : Pick < IFileSystem , 'readFile ' > ,
110+ fileSystem : Pick < IFileSystem , 'readTail ' > ,
115111 proxyLogPath : string | undefined ,
116112 tailLineCount : number = PROXY_LOG_TAIL_LINES
117113) : Promise < string | undefined > {
118114 if ( ! proxyLogPath ) {
119115 return undefined ;
120116 }
121117 try {
122- const logContent = await fileSystem . readFile ( proxyLogPath , 'utf-8' ) ;
118+ const logContent = await fileSystem . readTail ( proxyLogPath , PROXY_LOG_TAIL_MAX_BYTES ) ;
123119 return sanitizeStderrTail ( logContent , {
124120 maxLines : tailLineCount ,
125- maxChars : PROXY_LOG_TAIL_CHARS
121+ maxChars : PROXY_LOG_TAIL_MAX_BYTES
126122 } ) ;
127123 } catch ( logReadError ) {
128124 if ( ( logReadError as NodeJS . ErrnoException ) ?. code === 'ENOENT' ) {
@@ -155,13 +151,6 @@ export function buildProxyFailureErrorDetails(
155151 proxyLogTail
156152 } ;
157153
158- // Try to capture raw error object
159- try {
160- errorDetails . raw = JSON . stringify ( error ) ;
161- } catch {
162- errorDetails . raw = 'Error not JSON serializable' ;
163- }
164-
165154 return errorDetails ;
166155}
167156
0 commit comments