Silence a few common errors when fetching (#404)
Downgrade nodeinfo json error to a captured message
This commit is contained in:
parent
fa688a5a73
commit
18b50ce0e6
|
@ -1,4 +1,5 @@
|
|||
import hashlib
|
||||
import json
|
||||
import mimetypes
|
||||
import re
|
||||
from collections.abc import Iterable
|
||||
|
@ -872,12 +873,15 @@ class Post(StatorModel):
|
|||
f"Error fetching post from {object_uri}: {response.status_code}",
|
||||
{response.content},
|
||||
)
|
||||
post = cls.by_ap(
|
||||
canonicalise(response.json(), include_security=True),
|
||||
create=True,
|
||||
update=True,
|
||||
fetch_author=True,
|
||||
)
|
||||
try:
|
||||
post = cls.by_ap(
|
||||
canonicalise(response.json(), include_security=True),
|
||||
create=True,
|
||||
update=True,
|
||||
fetch_author=True,
|
||||
)
|
||||
except (json.JSONDecodeError, ValueError):
|
||||
raise cls.DoesNotExist(f"Invalid ld+json response for {object_uri}")
|
||||
# We may need to fetch the author too
|
||||
if post.author.state == IdentityStates.outdated:
|
||||
async_to_sync(post.author.fetch_actor)()
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import json
|
||||
import ssl
|
||||
from typing import Optional
|
||||
|
||||
import httpx
|
||||
|
@ -7,6 +8,7 @@ from asgiref.sync import sync_to_async
|
|||
from django.conf import settings
|
||||
from django.db import models
|
||||
|
||||
from core.exceptions import capture_message
|
||||
from stator.models import State, StateField, StateGraph, StatorModel
|
||||
from users.schemas import NodeInfo
|
||||
|
||||
|
@ -164,6 +166,8 @@ class Domain(StatorModel):
|
|||
)
|
||||
except httpx.HTTPError:
|
||||
pass
|
||||
except ssl.SSLCertVerificationError:
|
||||
return None
|
||||
else:
|
||||
try:
|
||||
for link in response.json().get("links", []):
|
||||
|
@ -183,7 +187,7 @@ class Domain(StatorModel):
|
|||
headers={"Accept": "application/json"},
|
||||
)
|
||||
response.raise_for_status()
|
||||
except httpx.HTTPError as ex:
|
||||
except (httpx.HTTPError, ssl.SSLCertVerificationError) as ex:
|
||||
response = getattr(ex, "response", None)
|
||||
if (
|
||||
response
|
||||
|
@ -199,9 +203,10 @@ class Domain(StatorModel):
|
|||
try:
|
||||
info = NodeInfo(**response.json())
|
||||
except json.JSONDecodeError as ex:
|
||||
raise ValueError(
|
||||
capture_message(
|
||||
f"Client error decoding nodeinfo: domain={self.domain}, error={str(ex)}"
|
||||
)
|
||||
return None
|
||||
return info
|
||||
|
||||
@property
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import ssl
|
||||
from functools import cached_property, partial
|
||||
from typing import Literal
|
||||
from urllib.parse import urlparse
|
||||
|
@ -642,7 +643,10 @@ class Identity(StatorModel):
|
|||
(actor uri, canonical handle) or None, None if it does not resolve.
|
||||
"""
|
||||
domain = handle.split("@")[1].lower()
|
||||
webfinger_url = await cls.fetch_webfinger_url(domain)
|
||||
try:
|
||||
webfinger_url = await cls.fetch_webfinger_url(domain)
|
||||
except ssl.SSLCertVerificationError:
|
||||
return None, None
|
||||
|
||||
# Go make a Webfinger request
|
||||
async with httpx.AsyncClient(
|
||||
|
@ -656,7 +660,7 @@ class Identity(StatorModel):
|
|||
headers={"Accept": "application/json"},
|
||||
)
|
||||
response.raise_for_status()
|
||||
except httpx.RequestError as ex:
|
||||
except (httpx.HTTPError, ssl.SSLCertVerificationError) as ex:
|
||||
response = getattr(ex, "response", None)
|
||||
if (
|
||||
response
|
||||
|
@ -703,25 +707,24 @@ class Identity(StatorModel):
|
|||
method="get",
|
||||
uri=self.actor_uri,
|
||||
)
|
||||
except httpx.RequestError:
|
||||
except (httpx.RequestError, ssl.SSLCertVerificationError):
|
||||
return False
|
||||
content_type = response.headers.get("content-type")
|
||||
if content_type and "html" in content_type:
|
||||
# Some servers don't properly handle "application/activity+json"
|
||||
return False
|
||||
if response.status_code == 410:
|
||||
# Their account got deleted, so let's do the same.
|
||||
if self.pk:
|
||||
status_code = response.status_code
|
||||
if status_code >= 400:
|
||||
if status_code == 410 and self.pk:
|
||||
# Their account got deleted, so let's do the same.
|
||||
await Identity.objects.filter(pk=self.pk).adelete()
|
||||
return False
|
||||
if response.status_code == 404:
|
||||
# We don't trust this as much as 410 Gone, but skip for now
|
||||
return False
|
||||
if response.status_code >= 500:
|
||||
return False
|
||||
if response.status_code >= 400:
|
||||
|
||||
if status_code >= 500 or status_code in [403, 404, 410]:
|
||||
# Common errors with other server, not worth reporting
|
||||
return False
|
||||
|
||||
raise ValueError(
|
||||
f"Client error fetching actor at {self.actor_uri}: {response.status_code}",
|
||||
f"Client error fetching actor at {self.actor_uri}: {status_code}",
|
||||
response.content,
|
||||
)
|
||||
document = canonicalise(response.json(), include_security=True)
|
||||
|
|
Loading…
Reference in New Issue