diff --git a/src/NetPulse.Cli/Program.cs b/src/NetPulse.Cli/Program.cs
index d1f4954..3219d1b 100644
--- a/src/NetPulse.Cli/Program.cs
+++ b/src/NetPulse.Cli/Program.cs
@@ -1,5 +1,6 @@
using System.Net.NetworkInformation;
using NetPulse.Core.Domain;
+using NetPulse.Core.Services;
if (args.Length == 0)
{
@@ -18,15 +19,32 @@ switch (command)
return;
}
- var target = args[1];
- await RunPingAsync(target);
+ var service = new PingService();
+ var result = await service.RunAsync(Guid.Empty, args[1]);
+ Console.WriteLine(result.Success
+ ? $"Success: {result.LatencyMs} ms"
+ : $"Failed: {result.ErrorMessage}");
+ if (!result.Success && result.InnerErrorMessage is not null)
+ {
+ Console.WriteLine($"Inner error: {result.InnerErrorMessage}");
+ }
+
break;
-
- default:
- Console.WriteLine($"Unkown command: {command}");
- break;
}
+/*
+===========================================================
+ARCHIVE NOTE — Old Ping Logic (Lesson 2 → Pre-Service Layer)
+Keeping this for reference only. Not compiled. Not used.
+This was the original inline/local-function ping approach
+before we migrated to the proper PingService architecture.
+
+Useful for:
+- remembering how PingResult was initially populated
+- comparing exception handling approaches
+- seeing the progression of the codebase over lessons
+- nostalgia (optional but valid)
+===========================================================
static async Task RunPingAsync(string target)
{
using var pinger = new Ping();
@@ -61,6 +79,7 @@ static async Task RunPingAsync(string target)
}
}
+
static void SaveMockResult(PingResult result)
{
Console.WriteLine(" --- Saved Result ---");
@@ -69,3 +88,7 @@ static void SaveMockResult(PingResult result)
Console.WriteLine($"Latency: {result.LatencyMs}");
Console.WriteLine($"Error: {result.ErrorMessage}");
}
+===========================================================
+End of Archive Block
+===========================================================
+*/
\ No newline at end of file
diff --git a/src/NetPulse.Core/Domain/PingResult.cs b/src/NetPulse.Core/Domain/PingResult.cs
index ad0c729..21459dd 100644
--- a/src/NetPulse.Core/Domain/PingResult.cs
+++ b/src/NetPulse.Core/Domain/PingResult.cs
@@ -31,4 +31,9 @@ public class PingResult
/// Error detail if the pin failed.
///
public string? ErrorMessage { get; init; }
+
+ ///
+ /// InnerErrorMessage for error handling
+ ///
+ public string? InnerErrorMessage { get; init; }
}
\ No newline at end of file
diff --git a/src/NetPulse.Core/Services/PingService.cs b/src/NetPulse.Core/Services/PingService.cs
new file mode 100644
index 0000000..b44e3b7
--- /dev/null
+++ b/src/NetPulse.Core/Services/PingService.cs
@@ -0,0 +1,61 @@
+using System.Net.NetworkInformation;
+using NetPulse.Core.Domain;
+
+namespace NetPulse.Core.Services;
+
+public class PingService
+{
+ private readonly Ping _pinger = new();
+
+ public async Task RunAsync(Guid targetId, string host)
+ {
+ try
+ {
+ var reply = await _pinger.SendPingAsync(host, 2000);
+
+ if (reply.Status == IPStatus.Success)
+ {
+ return new PingResult
+ {
+ TargetId = targetId,
+ Timestamputc = DateTime.UtcNow,
+ Success = true,
+ LatencyMs = reply.RoundtripTime,
+ ErrorMessage = null
+ };
+ }
+
+ return new PingResult
+ {
+ TargetId = targetId,
+ Timestamputc = DateTime.UtcNow,
+ Success = false,
+ LatencyMs = null,
+ ErrorMessage = $"Ping failed with status: {reply.Status}"
+ };
+ }
+ catch (PingException ex)
+ {
+ return new PingResult
+ {
+ TargetId = targetId,
+ Timestamputc = DateTime.UtcNow,
+ Success = false,
+ LatencyMs = null,
+ ErrorMessage = ex.Message,
+ InnerErrorMessage = ex.InnerException?.Message
+ };
+ }
+ catch (Exception ex)
+ {
+ return new PingResult
+ {
+ TargetId = targetId,
+ Timestamputc = DateTime.UtcNow,
+ Success = false,
+ LatencyMs = null,
+ ErrorMessage = ex.Message
+ };
+ }
+ }
+}
\ No newline at end of file