summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorHarmen Stoppels <harmenstoppels@gmail.com>2023-08-05 11:16:51 +0200
committerGitHub <noreply@github.com>2023-08-05 11:16:51 +0200
commitef544a3b6d695104ce67cb9d2b0ff0e776aa1b46 (patch)
tree276e366a4d0078e7e2931d59cadd19bb42f36755 /lib
parent4eed83265395ab52532765c3ae9448283e9ff55b (diff)
downloadspack-ef544a3b6d695104ce67cb9d2b0ff0e776aa1b46.tar.gz
spack-ef544a3b6d695104ce67cb9d2b0ff0e776aa1b46.tar.bz2
spack-ef544a3b6d695104ce67cb9d2b0ff0e776aa1b46.tar.xz
spack-ef544a3b6d695104ce67cb9d2b0ff0e776aa1b46.zip
Add a more detailed HTTPError (#39187)
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/util/web.py29
1 files changed, 26 insertions, 3 deletions
diff --git a/lib/spack/spack/util/web.py b/lib/spack/spack/util/web.py
index b4218a7b31..ffaa54d012 100644
--- a/lib/spack/spack/util/web.py
+++ b/lib/spack/spack/util/web.py
@@ -4,6 +4,7 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import codecs
+import email.message
import errno
import multiprocessing.pool
import os
@@ -16,7 +17,7 @@ import traceback
import urllib.parse
from html.parser import HTMLParser
from pathlib import Path, PurePosixPath
-from urllib.error import URLError
+from urllib.error import HTTPError, URLError
from urllib.request import HTTPSHandler, Request, build_opener
import llnl.util.lang
@@ -38,15 +39,37 @@ from spack.util.executable import CommandNotFoundError, which
from spack.util.path import convert_to_posix_path
+class DetailedHTTPError(HTTPError):
+ def __init__(self, req: Request, code: int, msg: str, hdrs: email.message.Message, fp) -> None:
+ self.req = req
+ super().__init__(req.get_full_url(), code, msg, hdrs, fp)
+
+ def __str__(self):
+ # Note: HTTPError, is actually a kind of non-seekable response object, so
+ # best not to read the response body here (even if it may include a human-readable
+ # error message).
+ return f"{self.req.get_method()} {self.url} returned {self.code}: {self.msg}"
+
+
+class SpackHTTPDefaultErrorHandler(urllib.request.HTTPDefaultErrorHandler):
+ def http_error_default(self, req, fp, code, msg, hdrs):
+ raise DetailedHTTPError(req, code, msg, hdrs, fp)
+
+
def _urlopen():
s3 = spack.s3_handler.UrllibS3Handler()
gcs = spack.gcs_handler.GCSHandler()
+ error_handler = SpackHTTPDefaultErrorHandler()
# One opener with HTTPS ssl enabled
- with_ssl = build_opener(s3, gcs, HTTPSHandler(context=ssl.create_default_context()))
+ with_ssl = build_opener(
+ s3, gcs, HTTPSHandler(context=ssl.create_default_context()), error_handler
+ )
# One opener with HTTPS ssl disabled
- without_ssl = build_opener(s3, gcs, HTTPSHandler(context=ssl._create_unverified_context()))
+ without_ssl = build_opener(
+ s3, gcs, HTTPSHandler(context=ssl._create_unverified_context()), error_handler
+ )
# And dynamically dispatch based on the config:verify_ssl.
def dispatch_open(fullurl, data=None, timeout=None):