From d7771f190f226a0537bf7f414758b4dc37c41ede Mon Sep 17 00:00:00 2001
From: Zack Galbreath <zack.galbreath@kitware.com>
Date: Thu, 29 Jul 2021 15:46:17 -0400
Subject: Catch ConnectionError from CDash reporter (#24818)

* Catch ConnectionError from CDash reporter

Catch ConnectionError when attempting to upload the results of `spack install`
to CDash. This follows in the spirit of #24299. We do not want `spack install`
to exit with a non-zero status when something goes wrong while attempting to
report results to CDash.

* Catch HTTP Error 400 (Bad Request) in relate_cdash_builds()
---
 lib/spack/spack/ci.py               | 25 ++++++++++++++-----------
 lib/spack/spack/reporters/cdash.py  | 27 +++++++++++++++------------
 lib/spack/spack/test/cmd/install.py |  3 +--
 3 files changed, 30 insertions(+), 25 deletions(-)

diff --git a/lib/spack/spack/ci.py b/lib/spack/spack/ci.py
index 7f3d88a925..0ada128f64 100644
--- a/lib/spack/spack/ci.py
+++ b/lib/spack/spack/ci.py
@@ -1316,17 +1316,20 @@ def relate_cdash_builds(spec_map, cdash_base_url, job_build_id, cdash_project,
 
         request = Request(cdash_api_url, data=enc_data, headers=headers)
 
-        response = opener.open(request)
-        response_code = response.getcode()
-
-        if response_code != 200 and response_code != 201:
-            msg = 'Relate builds ({0} -> {1}) failed (resp code = {2})'.format(
-                job_build_id, dep_build_id, response_code)
-            tty.warn(msg)
-            return
-
-        response_text = response.read()
-        tty.debug('Relate builds response: {0}'.format(response_text))
+        try:
+            response = opener.open(request)
+            response_code = response.getcode()
+
+            if response_code != 200 and response_code != 201:
+                msg = 'Relate builds ({0} -> {1}) failed (resp code = {2})'.format(
+                    job_build_id, dep_build_id, response_code)
+                tty.warn(msg)
+                return
+
+            response_text = response.read()
+            tty.debug('Relate builds response: {0}'.format(response_text))
+        except Exception as e:
+            print("Relating builds in CDash failed: {0}".format(e))
 
 
 def write_cdashid_to_mirror(cdashid, spec, mirror_url):
diff --git a/lib/spack/spack/reporters/cdash.py b/lib/spack/spack/reporters/cdash.py
index 24e4f2833a..cb9539b2d7 100644
--- a/lib/spack/spack/reporters/cdash.py
+++ b/lib/spack/spack/reporters/cdash.py
@@ -425,18 +425,21 @@ class CDash(Reporter):
             if self.authtoken:
                 request.add_header('Authorization',
                                    'Bearer {0}'.format(self.authtoken))
-            # By default, urllib2 only support GET and POST.
-            # CDash needs expects this file to be uploaded via PUT.
-            request.get_method = lambda: 'PUT'
-            response = opener.open(request)
-            if self.current_package_name not in self.buildIds:
-                resp_value = response.read()
-                if isinstance(resp_value, bytes):
-                    resp_value = resp_value.decode('utf-8')
-                match = self.buildid_regexp.search(resp_value)
-                if match:
-                    buildid = match.group(1)
-                    self.buildIds[self.current_package_name] = buildid
+            try:
+                # By default, urllib2 only support GET and POST.
+                # CDash needs expects this file to be uploaded via PUT.
+                request.get_method = lambda: 'PUT'
+                response = opener.open(request)
+                if self.current_package_name not in self.buildIds:
+                    resp_value = response.read()
+                    if isinstance(resp_value, bytes):
+                        resp_value = resp_value.decode('utf-8')
+                    match = self.buildid_regexp.search(resp_value)
+                    if match:
+                        buildid = match.group(1)
+                        self.buildIds[self.current_package_name] = buildid
+            except Exception as e:
+                print("Upload to CDash failed: {0}".format(e))
 
     def finalize_report(self):
         if self.buildIds:
diff --git a/lib/spack/spack/test/cmd/install.py b/lib/spack/spack/test/cmd/install.py
index 022db42ba2..6a84b97a8f 100644
--- a/lib/spack/spack/test/cmd/install.py
+++ b/lib/spack/spack/test/cmd/install.py
@@ -12,7 +12,6 @@ import time
 
 import pytest
 from six.moves import builtins
-from six.moves.urllib.error import HTTPError, URLError
 
 import llnl.util.filesystem as fs
 
@@ -491,7 +490,7 @@ def test_cdash_upload_build_error(tmpdir, mock_fetch, install_mockery,
     # capfd interferes with Spack's capturing
     with capfd.disabled():
         with tmpdir.as_cwd():
-            with pytest.raises((HTTPError, URLError)):
+            with pytest.raises(SpackError):
                 install(
                     '--log-format=cdash',
                     '--log-file=cdash_reports',
-- 
cgit v1.2.3-70-g09d2