Skip to content

Commit

Permalink
Downgrade most fetch related errors to capture_message (jointakahe#443)
Browse files Browse the repository at this point in the history
  • Loading branch information
manfre authored Jan 19, 2023
1 parent 47d9dc2 commit 51ae78a
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 20 deletions.
3 changes: 2 additions & 1 deletion activities/models/post.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import json
import mimetypes
import re
import ssl
from collections.abc import Iterable
from typing import Optional
from urllib.parse import urlparse
Expand Down Expand Up @@ -890,7 +891,7 @@ def by_object_uri(cls, object_uri, fetch=False) -> "Post":
response = async_to_sync(SystemActor().signed_request)(
method="get", uri=object_uri
)
except httpx.RequestError:
except (httpx.HTTPError, ssl.SSLCertVerificationError):
raise cls.DoesNotExist(f"Could not fetch {object_uri}")
if response.status_code in [404, 410]:
raise cls.DoesNotExist(f"No post at {object_uri}")
Expand Down
20 changes: 13 additions & 7 deletions core/signatures.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from django.utils import timezone
from django.utils.http import http_date, parse_http_date
from httpx._types import TimeoutTypes
from idna.core import InvalidCodepoint
from pyld import jsonld

from core.ld import format_ld_date
Expand Down Expand Up @@ -235,13 +236,18 @@ async def signed_request(
# Send the request with all those headers except the pseudo one
del headers["(request-target)"]
async with httpx.AsyncClient(timeout=timeout) as client:
response = await client.request(
method,
uri,
headers=headers,
content=body_bytes,
follow_redirects=method == "get",
)
try:
response = await client.request(
method,
uri,
headers=headers,
content=body_bytes,
follow_redirects=method == "get",
)
except InvalidCodepoint as ex:
# Convert to a more generic error we handle
raise httpx.HTTPError(f"InvalidCodepoint: {str(ex)}") from None

if (
method == "post"
and response.status_code >= 400
Expand Down
13 changes: 9 additions & 4 deletions users/models/domain.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,14 @@ async def fetch_nodeinfo(self) -> NodeInfo | None:
and response.status_code < 500
and response.status_code not in [401, 403, 404, 406, 410]
):
raise ValueError(
f"Client error fetching nodeinfo: domain={self.domain}, code={response.status_code}",
response.content,
capture_message(
f"Client error fetching nodeinfo: {str(ex)}",
extras={
"code": response.status_code,
"content": response.content,
"domain": self.domain,
"nodeinfo20_url": nodeinfo20_url,
},
)
return None

Expand All @@ -206,7 +211,7 @@ async def fetch_nodeinfo(self) -> NodeInfo | None:
except (json.JSONDecodeError, pydantic.ValidationError) as ex:
capture_message(
f"Client error decoding nodeinfo: {str(ex)}",
extra={
extras={
"domain": self.domain,
"nodeinfo20_url": nodeinfo20_url,
},
Expand Down
19 changes: 11 additions & 8 deletions users/models/identity.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from django.utils.functional import lazy
from lxml import etree

from core.exceptions import ActorMismatchError
from core.exceptions import ActorMismatchError, capture_message
from core.html import ContentRenderer, html_to_plaintext, strip_html
from core.ld import (
canonicalise,
Expand Down Expand Up @@ -723,14 +723,17 @@ async def fetch_actor(self) -> bool:
# Their account got deleted, so let's do the same.
await Identity.objects.filter(pk=self.pk).adelete()

if status_code >= 500 or status_code in [403, 404, 410]:
# Common errors with other server, not worth reporting
return False
if status_code < 500 and status_code not in [401, 403, 404, 406, 410]:
capture_message(
f"Client error fetching actor at {self.actor_uri}: {status_code}",
extras={
"identity": self.pk,
"domain": self.domain_id,
"content": response.content,
},
)
return False

raise ValueError(
f"Client error fetching actor at {self.actor_uri}: {status_code}",
response.content,
)
document = canonicalise(response.json(), include_security=True)
if "type" not in document:
return False
Expand Down

0 comments on commit 51ae78a

Please sign in to comment.