Add a more detailed HTTPError (#39187)

This commit is contained in:
Harmen Stoppels 2023-08-05 11:16:51 +02:00 committed by GitHub
parent 4eed832653
commit ef544a3b6d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -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 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.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):