Phase 11 complete: - ArgParser.cs: CLI parsing extracted from Program.cs (pure static method) - Program.cs: no static state; Scarica/Invia take explicit InputArgs param - Program.cs: try/finally with connected flag — fixes connection leak on exception - Program.cs: PrintErrors helper surfaces CncResult.Errors on every failure - AesCrypt.cs: deleted (dead code, zero references) - NcProgramManager.csproj: AesCrypt.cs → ArgParser.cs Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
5.1 KiB
5.1 KiB
| phase | plan | type | wave | depends_on | files_modified | autonomous | ||
|---|---|---|---|---|---|---|---|---|
| 11-refactor | 02 | execute | 2 |
|
|
true |
Purpose
Current code manually calls DisconnectAsync before each error return — but the catch block has no disconnect, so any unhandled exception after connect leaks the connection. Also, CncResult.Errors is never printed; operators get a numeric code with no machine-level detail.
Output
Program.cs— both methods refactored: singletry/catch/finallywithconnectedflag; allCncResultfailures print errors before returning- Private helper
PrintErrors(IReadOnlyList<CncError>)added
<acceptance_criteria>
AC-1: Disconnect always runs after connect
Given Scarica or Invia successfully calls ConnectAsync
When any exception is thrown during the operation
Then DisconnectAsync is called exactly once (via finally block)
AC-2: No manual disconnect before early returns
Given Scarica or Invia
When read
Then no call to DisconnectAsync exists inside the try block — only in the finally
AC-3: CncResult errors printed on failure
Given any CncResult<T> with Success == false and non-empty Errors list
When the result is checked and found failed
Then each error is printed via CncError.ToString() before VediErrore is called
</acceptance_criteria>
Task 1: Add PrintErrors helper + refactor Scarica Program.cs Add private static helper at bottom of Program class: ``` static void PrintErrors(System.Collections.Generic.IReadOnlyList errors) { if (errors == null) return; foreach (var e in errors) Console.WriteLine(" " + e.ToString()); } ```Refactor Scarica:
1. Declare `bool connected = false;` before try.
2. Wrap ALL operation logic in a single `try { } catch (Exception ex) { } finally { }`.
3. After `ConnectAsync` succeeds, set `connected = true`.
4. Remove ALL `macchina.DisconnectAsync().GetAwaiter().GetResult()` calls from inside the try block.
5. In `finally`: `if (connected) macchina.DisconnectAsync().GetAwaiter().GetResult();`
6. After every `!result.Success` check, call `PrintErrors(result.Errors)` before `VediErrore`.
Early-return on `!connResult.Success` does NOT set connected=true, so finally skips disconnect — correct.
Avoid: catching and swallowing the disconnect exception in finally (let it propagate naturally).
Read Program.cs Scarica method:
- `connected` flag declared
- `finally { if (connected) macchina.DisconnectAsync()... }` present
- Zero `DisconnectAsync` calls inside try block
- `PrintErrors` called before each `VediErrore(-2XX)` that follows a CncResult check
AC-1, AC-2, AC-3 satisfied for Scarica
Task 2: Refactor Invia with same pattern
Program.cs
Apply identical refactor to Invia:
1. Declare `bool connected = false;` before try.
2. Single `try/catch/finally` — set `connected = true` after `ConnectAsync` succeeds.
3. Remove ALL `macchina.DisconnectAsync()` calls from inside try.
4. `finally { if (connected) macchina.DisconnectAsync().GetAwaiter().GetResult(); }`
5. Call `PrintErrors(result.Errors)` before each `VediErrore` that follows a failed CncResult.
Note: `File.ReadAllText` in Invia can throw IOException — the finally will still run and disconnect safely.
Read Program.cs Invia method:
- Same structure as Scarica post-refactor
- Zero `DisconnectAsync` calls inside try
- `PrintErrors` called on all failed CncResult checks
AC-1, AC-2, AC-3 satisfied for Invia
DO NOT CHANGE
- ArgParser.cs
- InputArgs.cs
- Cnc/* — all machine implementation files
- Licensing/*
- VediErrore content or error codes
- MostraAiuto
- NcProgramManager.Tests/*
SCOPE LIMITS
- Only Program.cs touched
- Do not change method signatures
- Do not add new error codes
- Do not change the connection/operation logic — only the cleanup and error display
<success_criteria>
- Both Scarica and Invia use try/catch/finally with connected flag
- DisconnectAsync called only in finally
- PrintErrors called on every CncResult failure
- Zero compilation errors </success_criteria>