I ended up doing the following:
broken_urls = {}
for item in web_map_items:
web_map = WebMap(item)
print("-" * 79)
print(f"Checking web map '{item.title}' (id: {item.id})...")
layers = [layer for layer in web_map.layers + web_map.basemap.baseMapLayers if hasattr(layer, "url")]
for layer in layers:
try:
response = requests.get(
url=layer.url,
params={"f": "json"}
)
response = json.loads(response.text)
try:
print(f"[✗] {layer.title}: layer URL returned {response['error']}. {layer.url}")
broken_urls.setdefault(item.title + " - " + item.id, []).append(f"{layer.title}: layer URL returned {response['error']}. {layer.url}")
except:
print(f"[✓] {layer.title}: layer URL is working.")
except requests.ConnectionError as e:
print(f"[✗] {layer.url}: unable to reach layer due to '{e}'")
broken_urls.setdefault(item.title + " - " + item.id, []).append(f"{layer.title}: unable to reach layer due to '{e}'. {layer.url}")
Looking at the response header doesn't work because layers return a 200 regardless of whether the layer url is functional in a web map. The actual error is in the json.
For the email component I used the arcgis.gis.Group.notify function.