From ea105d65f858e5cab91711de1f557e751dfe313b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kol=C3=A1rik?= Date: Sun, 29 Mar 2026 20:46:34 +0200 Subject: [PATCH 1/2] fix: early exit with an offline probe in --latency --- view/latency.go | 4 ++++ view/latency_test.go | 50 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/view/latency.go b/view/latency.go index dcdb035..f394efd 100644 --- a/view/latency.go +++ b/view/latency.go @@ -17,6 +17,10 @@ func (v *viewer) OutputLatency(id string, measurement *globalping.Measurement) e } v.printer.ErrPrintln(v.getProbeInfo(&result)) + if result.Result.Status != globalping.StatusFinished { + v.printer.Println(result.Result.RawOutput) + continue + } switch v.ctx.Cmd { case "ping": diff --git a/view/latency_test.go b/view/latency_test.go index b596125..333810d 100644 --- a/view/latency_test.go +++ b/view/latency_test.go @@ -23,6 +23,7 @@ func Test_Output_Latency_Ping(t *testing.T) { Tags: []string{"tag-1"}, }, Result: globalping.ProbeResult{ + Status: globalping.StatusFinished, StatsRaw: json.RawMessage(`{"min":8,"avg":12,"max":20}`), }, }, @@ -37,6 +38,7 @@ func Test_Output_Latency_Ping(t *testing.T) { Tags: []string{"tag B"}, }, Result: globalping.ProbeResult{ + Status: globalping.StatusFinished, StatsRaw: json.RawMessage(`{"min":9,"avg":15,"max":22}`), }, }, @@ -81,6 +83,7 @@ func Test_Output_Latency_Ping_StylingDisabled(t *testing.T) { Tags: []string{"tag"}, }, Result: globalping.ProbeResult{ + Status: globalping.StatusFinished, StatsRaw: json.RawMessage(`{"min":8,"avg":12,"max":20}`), }, }, @@ -124,6 +127,7 @@ func Test_Output_Latency_DNS(t *testing.T) { Tags: []string{"tag"}, }, Result: globalping.ProbeResult{ + Status: globalping.StatusFinished, TimingsRaw: []byte(`{"total": 44}`), }, }, @@ -161,6 +165,7 @@ func Test_Output_Latency_DNS_StylingDisabled(t *testing.T) { Tags: []string{"tag"}, }, Result: globalping.ProbeResult{ + Status: globalping.StatusFinished, TimingsRaw: []byte(`{"total": 44}`), }, }, @@ -202,6 +207,7 @@ func Test_Output_Latency_Http(t *testing.T) { Tags: []string{"tag"}, }, Result: globalping.ProbeResult{ + Status: globalping.StatusFinished, TimingsRaw: []byte(`{"total": 44,"download":11,"firstByte":20,"dns":5,"tls":2,"tcp":4}`), }, }, @@ -244,6 +250,7 @@ func Test_Output_Latency_Http_StylingDisabled(t *testing.T) { Tags: []string{"tag"}, }, Result: globalping.ProbeResult{ + Status: globalping.StatusFinished, TimingsRaw: []byte(`{"total": 44,"download":11,"firstByte":20,"dns":5,"tls":2,"tcp":4}`), }, }, @@ -277,3 +284,46 @@ TCP: 4 ms `, w.String()) } + +func Test_Output_Latency_Offline(t *testing.T) { + measurement := &globalping.Measurement{ + Results: []globalping.ProbeMeasurement{ + { + Probe: globalping.ProbeDetails{ + Continent: "Continent", + Country: "Country", + State: "State", + City: "City", + ASN: 12345, + Network: "Network", + }, + Result: globalping.ProbeResult{ + Status: globalping.MeasurementStatus("offline"), + RawOutput: "This probe is currently offline. Please try again later.", + }, + }, + }, + } + + w := new(bytes.Buffer) + errW := new(bytes.Buffer) + printer := NewPrinter(nil, w, errW) + printer.DisableStyling() + viewer := NewViewer( + &Context{ + Cmd: "ping", + ToLatency: true, + Share: true, + }, + printer, + nil, + ) + + err := viewer.OutputLatency(measurementID1, measurement) + assert.NoError(t, err) + + assert.Equal(t, `> City (State), Country, Continent, Network (AS12345) +> View the results online: https://globalping.io?measurement=1zGzfAGL7sZfUs3c +`, errW.String()) + assert.Equal(t, "This probe is currently offline. Please try again later.\n\n", w.String()) +} From cf6760ca3cfa7d0f61bbbabfa7cd740854f00446 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kol=C3=A1rik?= Date: Sun, 29 Mar 2026 20:46:56 +0200 Subject: [PATCH 2/2] fix: offline handling in infinite mode --- view/infinite.go | 10 +++++----- view/infinite_test.go | 23 +++++++++++++++++++++++ 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/view/infinite.go b/view/infinite.go index 6366a1a..8ba3e7f 100644 --- a/view/infinite.go +++ b/view/infinite.go @@ -24,7 +24,7 @@ var ( ) func (v *viewer) OutputInfinite(measurement *globalping.Measurement) error { - if isFailedMeasurement(measurement) { + if measurement.Status != globalping.StatusInProgress && !isSomeTestFinished(measurement) { return v.outputFailSummary(measurement) } @@ -104,13 +104,13 @@ func (v *viewer) outputFailSummary(m *globalping.Measurement) error { return errors.New("all probes failed") } -func isFailedMeasurement(m *globalping.Measurement) bool { +func isSomeTestFinished(m *globalping.Measurement) bool { for i := range m.Results { - if m.Results[i].Result.Status != globalping.StatusFailed { - return false + if m.Results[i].Result.Status == globalping.StatusFinished { + return true } } - return true + return false } func formatDuration(ms float64) string { diff --git a/view/infinite_test.go b/view/infinite_test.go index f0a51ca..27b32d1 100644 --- a/view/infinite_test.go +++ b/view/infinite_test.go @@ -464,6 +464,29 @@ ping: cdn.jsdelivr.net.xc: Name or service not known assert.Nil(t, ctx.AggregatedStats) } +func Test_OutputInfinite_SingleProbe_Offline(t *testing.T) { + measurement := createPingMeasurement(measurementID1) + measurement.Status = globalping.StatusFinished + measurement.Results[0].Result.Status = "offline" + measurement.Results[0].Result.RawOutput = `This probe is currently offline. Please try again later.` + + ctx := createDefaultContext("ping") + w := new(bytes.Buffer) + printer := NewPrinter(nil, w, w) + printer.DisableStyling() + viewer := NewViewer(ctx, printer, nil) + err := viewer.OutputInfinite(measurement) + + assert.Equal(t, "all probes failed", err.Error()) + assert.Equal(t, + `> Berlin, DE, EU, Deutsche Telekom AG (AS3320) +This probe is currently offline. Please try again later. +`, + w.String(), + ) + assert.Nil(t, ctx.AggregatedStats) +} + func Test_FormatDuration(t *testing.T) { d := formatDuration(1.2345) assert.Equal(t, "1.23 ms", d)