Downgrade most fetch related errors to capture_message (#443)

This commit is contained in:
Michael Manfre 2023-01-19 15:14:55 -05:00 committed by GitHub
parent 47d9dc2488
commit 51ae78a33c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 35 additions and 20 deletions

View file

@ -3,6 +3,7 @@ import hashlib
import json import json
import mimetypes import mimetypes
import re import re
import ssl
from collections.abc import Iterable from collections.abc import Iterable
from typing import Optional from typing import Optional
from urllib.parse import urlparse from urllib.parse import urlparse
@ -890,7 +891,7 @@ class Post(StatorModel):
response = async_to_sync(SystemActor().signed_request)( response = async_to_sync(SystemActor().signed_request)(
method="get", uri=object_uri method="get", uri=object_uri
) )
except httpx.RequestError: except (httpx.HTTPError, ssl.SSLCertVerificationError):
raise cls.DoesNotExist(f"Could not fetch {object_uri}") raise cls.DoesNotExist(f"Could not fetch {object_uri}")
if response.status_code in [404, 410]: if response.status_code in [404, 410]:
raise cls.DoesNotExist(f"No post at {object_uri}") raise cls.DoesNotExist(f"No post at {object_uri}")

View file

@ -12,6 +12,7 @@ from django.http import HttpRequest
from django.utils import timezone from django.utils import timezone
from django.utils.http import http_date, parse_http_date from django.utils.http import http_date, parse_http_date
from httpx._types import TimeoutTypes from httpx._types import TimeoutTypes
from idna.core import InvalidCodepoint
from pyld import jsonld from pyld import jsonld
from core.ld import format_ld_date from core.ld import format_ld_date
@ -235,13 +236,18 @@ class HttpSignature:
# Send the request with all those headers except the pseudo one # Send the request with all those headers except the pseudo one
del headers["(request-target)"] del headers["(request-target)"]
async with httpx.AsyncClient(timeout=timeout) as client: async with httpx.AsyncClient(timeout=timeout) as client:
response = await client.request( try:
method, response = await client.request(
uri, method,
headers=headers, uri,
content=body_bytes, headers=headers,
follow_redirects=method == "get", 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 ( if (
method == "post" method == "post"
and response.status_code >= 400 and response.status_code >= 400

View file

@ -195,9 +195,14 @@ class Domain(StatorModel):
and response.status_code < 500 and response.status_code < 500
and response.status_code not in [401, 403, 404, 406, 410] and response.status_code not in [401, 403, 404, 406, 410]
): ):
raise ValueError( capture_message(
f"Client error fetching nodeinfo: domain={self.domain}, code={response.status_code}", f"Client error fetching nodeinfo: {str(ex)}",
response.content, extras={
"code": response.status_code,
"content": response.content,
"domain": self.domain,
"nodeinfo20_url": nodeinfo20_url,
},
) )
return None return None
@ -206,7 +211,7 @@ class Domain(StatorModel):
except (json.JSONDecodeError, pydantic.ValidationError) as ex: except (json.JSONDecodeError, pydantic.ValidationError) as ex:
capture_message( capture_message(
f"Client error decoding nodeinfo: {str(ex)}", f"Client error decoding nodeinfo: {str(ex)}",
extra={ extras={
"domain": self.domain, "domain": self.domain,
"nodeinfo20_url": nodeinfo20_url, "nodeinfo20_url": nodeinfo20_url,
}, },

View file

@ -12,7 +12,7 @@ from django.utils import timezone
from django.utils.functional import lazy from django.utils.functional import lazy
from lxml import etree 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.html import ContentRenderer, html_to_plaintext, strip_html
from core.ld import ( from core.ld import (
canonicalise, canonicalise,
@ -723,14 +723,17 @@ class Identity(StatorModel):
# Their account got deleted, so let's do the same. # Their account got deleted, so let's do the same.
await Identity.objects.filter(pk=self.pk).adelete() await Identity.objects.filter(pk=self.pk).adelete()
if status_code >= 500 or status_code in [403, 404, 410]: if status_code < 500 and status_code not in [401, 403, 404, 406, 410]:
# Common errors with other server, not worth reporting capture_message(
return False 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) document = canonicalise(response.json(), include_security=True)
if "type" not in document: if "type" not in document:
return False return False