Repository: alexjustesen/speedtest-tracker (language: php)

Issue:
Speedtest stuck in "Started" when can't reach icanhazip.com
**Describe the bug**
If the container is unable to reach `http://icanhazip.com`, speedtests will be stuck in **starting**.  

AFAIK, this was introduced in https://github.com/alexjustesen/speedtest-tracker/pull/1714 in https://github.com/alexjustesen/speedtest-tracker/releases/tag/v0.22.0

This appears to be the root cause of https://github.com/alexjustesen/speedtest-tracker/issues/1821

NOTE: The container is able to fully reach speedtest.net.

**To Reproduce**
Steps to reproduce the behavior:
1. Prevent access to `http://icanhazip.com`.  One way is running a pi-hole on network.
2. Click on Run Speedtest 
4. See error

**Expected behavior**
There should not be a critical dependencies on `http://icanhazip.com`.  Instead, fail gracefully, by running the test.  Or allow to disable this check in configuration.

**Background**
This domain is blocked in the Easy Privacy list which is used by several ad blockers, example NextDns.io

https://github.com/easylist/easylist/issues/15562


**Environment (please complete the following information):**
 - OS: [e.g. Ubuntu]
-  Architecture: [e.g. arm64, amd64]
 - Browser [e.g. chrome, safari]
 - Version [e.g. v1]

**Screenshots**
From #1821:
![image](https://github.com/user-attachments/assets/554de207-e000-42f5-ad5a-6ccd2fe8a5f0)


**Logs**
no logs

**Additional context**
Add any other context about the problem here.



Discussion / hints:

Fix patch:
diff --git a/app/Actions/GetExternalIpAddress.php b/app/Actions/GetExternalIpAddress.php
index a2b6ee451..6a4d0b114 100644
--- a/app/Actions/GetExternalIpAddress.php
+++ b/app/Actions/GetExternalIpAddress.php
@@ -2,11 +2,11 @@
 
 namespace App\Actions;
 
-use Illuminate\Support\Facades\Cache;
 use Illuminate\Support\Facades\Http;
 use Illuminate\Support\Facades\Log;
 use Illuminate\Support\Str;
 use Lorisleiva\Actions\Concerns\AsAction;
+use Throwable;
 
 class GetExternalIpAddress
 {
@@ -14,21 +14,16 @@ class GetExternalIpAddress
 
     public function handle(): bool|string
     {
-        $externalIp = Cache::remember('external_ip', 30, function (): bool|string {
+        try {
             $response = Http::retry(3, 100)
-                ->get('https://icanhazip.com/');
+                ->timeout(5)
+                ->get(url: 'https://icanhazip.com/');
+        } catch (Throwable $e) {
+            Log::error('Failed to fetch external IP address.', [$e->getMessage()]);
 
-            if ($response->failed()) {
-                $message = sprintf('Failed to fetch external IP address, %d', $response->status());
+            return false;
+        }
 
-                Log::warning($message);
-
-                return false;
-            }
-
-            return Str::trim($response->body());
-        });
-
-        return $externalIp;
+        return Str::trim($response->body());
     }
 }
diff --git a/app/Filament/Pages/Dashboard.php b/app/Filament/Pages/Dashboard.php
index bdbb940a8..c6c161b85 100644
--- a/app/Filament/Pages/Dashboard.php
+++ b/app/Filament/Pages/Dashboard.php
@@ -57,7 +57,6 @@ protected function getHeaderActions(): array
                     Forms\Components\Select::make('server_id')
                         ->label('Select Server')
                         ->helperText('Leave empty to run the speedtest without specifying a server.')
-                        ->options(fn (): array => GetOoklaSpeedtestServers::run())
                         ->options(function (): array {
                             return array_filter([
                                 'Manual servers' => Ookla::getConfigServers(),


Test patch:
diff --git a/app/Actions/GetOoklaSpeedtestServers.php b/app/Actions/GetOoklaSpeedtestServers.php
index 1d483e653..fe8e6a6ee 100644
--- a/app/Actions/GetOoklaSpeedtestServers.php
+++ b/app/Actions/GetOoklaSpeedtestServers.php
@@ -2,11 +2,10 @@
 
 namespace App\Actions;
 
-use Illuminate\Http\Client\RequestException;
-use Illuminate\Http\Client\Response;
 use Illuminate\Support\Facades\Http;
 use Illuminate\Support\Facades\Log;
 use Lorisleiva\Actions\Concerns\AsAction;
+use Throwable;
 
 class GetOoklaSpeedtestServers
 {
@@ -20,19 +19,19 @@ public function handle(): array
             'limit' => 20,
         ];
 
-        $response = Http::retry(3, 250)
-            ->timeout(5)
-            ->get(url: 'https://www.speedtest.net/api/js/servers', query: $query)
-            ->throw(function (Response $response, RequestException $e) {
-                Log::error($e);
+        try {
+            $response = Http::retry(3, 250)
+                ->timeout(5)
+                ->get(url: 'https://www.speedtest.net/api/js/servers', query: $query);
+        } catch (Throwable $e) {
+            Log::error('Unable to retrieve Ookla servers.', [$e->getMessage()]);
 
-                return [
-                    '0' => 'There was an issue retrieving Ookla speedtest servers, check the logs for more info.',
-                ];
-            })
-            ->collect();
+            return [
+                '⚠️ Unable to retrieve Ookla servers, check internet connection and see logs.',
+            ];
+        }
 
-        return $response->mapWithKeys(function (array $item, int $key) {
+        return $response->collect()->mapWithKeys(function (array $item, int $key) {
             return [
                 $item['id'] => $item['sponsor'].' ('.$item['name'].', '.$item['id'].')',
             ];