Severity: Warning
Location: src/Servy.Service/ProcessManagement/ProcessLauncher.cs:105-112
Code:
var encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false); // UTF-8 without BOM
// Save logs if paths are set
if (!string.IsNullOrWhiteSpace(options.StdOutPath))
{
File.AppendAllText(options.StdOutPath, stdoutBuffer.ToString(), encoding);
}
if (!string.IsNullOrWhiteSpace(options.StdErrPath))
{
File.AppendAllText(options.StdErrPath, stderrBuffer.ToString(), encoding);
}
Explanation:
After a synchronous process launch, the captured stdout and stderr buffers are flushed to disk via File.AppendAllText with no try/catch. If the target path is unwritable (disk full, permission error, network path down, read-only attribute, file currently locked by another writer), the call throws an IOException / UnauthorizedAccessException that propagates out of ProcessLauncher.Start(...) — and the in-memory buffer is lost with the stack unwind.
This is exactly the scenario where the captured output matters most: a service is failing, its logs fill the buffer with the diagnostic evidence, and the very call that's supposed to persist that evidence throws — leaving the operator with no trace of what happened.
Suggested fix:
Wrap each AppendAllText in a try/catch, log the failure via logger.Error with the path and exception, and include a short prefix of the lost buffer in the log message so at least some evidence survives:
try
{
File.AppendAllText(options.StdOutPath, stdoutBuffer.ToString(), encoding);
}
catch (Exception ex)
{
logger.Error($"Failed to persist captured stdout to '{options.StdOutPath}': {ex.Message}. First 512 chars: {stdoutBuffer.ToString().Substring(0, Math.Min(512, stdoutBuffer.Length))}", ex);
}
Do not re-throw — the process has already run and the caller needs the IProcessWrapper return value regardless.
Severity: Warning
Location:
src/Servy.Service/ProcessManagement/ProcessLauncher.cs:105-112Code:
Explanation:
After a synchronous process launch, the captured stdout and stderr buffers are flushed to disk via
File.AppendAllTextwith no try/catch. If the target path is unwritable (disk full, permission error, network path down, read-only attribute, file currently locked by another writer), the call throws anIOException/UnauthorizedAccessExceptionthat propagates out ofProcessLauncher.Start(...)— and the in-memory buffer is lost with the stack unwind.This is exactly the scenario where the captured output matters most: a service is failing, its logs fill the buffer with the diagnostic evidence, and the very call that's supposed to persist that evidence throws — leaving the operator with no trace of what happened.
Suggested fix:
Wrap each
AppendAllTextin a try/catch, log the failure vialogger.Errorwith the path and exception, and include a short prefix of the lost buffer in the log message so at least some evidence survives:Do not re-throw — the process has already run and the caller needs the
IProcessWrapperreturn value regardless.