Skip to content

[Code Quality] ProcessLaunchOptions.TimeoutMs — XML doc says 0 = infinite wait but ProcessLauncher.Start throws ArgumentException when TimeoutMs <= 0 #976

@Christophe-Rogiers

Description

@Christophe-Rogiers

Severity: Info

File: src/Servy.Service/ProcessManagement/ProcessLaunchOptions.cs

Line: 42-46

Code:

/// <summary>
/// Gets or sets the maximum time, in milliseconds, to wait for the process to exit.
/// Only applicable when <see cref="FireAndForget"/> is false. A value of 0 indicates an infinite wait.
/// </summary>
public int TimeoutMs { get; set; } = 0;

And in ProcessLauncher.cs:

// Synchronous mode: Wait for exit while pulsing the SCM
if (options.TimeoutMs <= 0)
{
    throw new ArgumentException(
        "Synchronous launch requires TimeoutMs > 0. Set FireAndForget = true for unbounded launches.",
        nameof(options));
}

Explanation:

The DTO documents TimeoutMs = 0 as an "infinite wait" and uses 0 as the property's default value. But ProcessLauncher.Start actively rejects that value: any synchronous launch with TimeoutMs == 0 throws ArgumentException("Synchronous launch requires TimeoutMs > 0. Set FireAndForget = true for unbounded launches.").

So in practice:

  • The default value of the property is always invalid for synchronous launches.
  • The documented "infinite wait" semantics are not implemented anywhere — to wait forever you must set FireAndForget = true, which is a different mode entirely.
  • A caller who reads the XML doc and uses the default constructor + sync mode hits a mid-run exception instead of getting an infinite wait.

Suggested fix — pick one:

  1. Update the XML doc to match reality (recommended):

    /// A positive timeout, in milliseconds, to wait for the process to exit.
    /// Only applicable when <see cref="FireAndForget"/> is false; required to be &gt; 0
    /// in synchronous mode. Use <see cref="FireAndForget"/> = true for unbounded launches.

    And consider initializing the default to a sane synchronous value (or leaving it at 0 but flagging that the caller MUST set it).

  2. Honor the documented behavior in ProcessLauncher.Start by treating TimeoutMs <= 0 as Timeout.Infinite and removing the throw.

The current state — doc and runtime contract disagreeing on what 0 means — is the worst of both options.

Metadata

Metadata

Assignees

Labels

documentationImprovements or additions to documentation

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions