mirror of
https://github.com/jointakahe/takahe.git
synced 2025-02-18 00:25:20 +00:00
Separate out timeouts from other remote server issues (#645)
This commit is contained in:
parent
1e8a392e57
commit
b60e807b91
3 changed files with 53 additions and 15 deletions
|
@ -168,6 +168,24 @@ def test_fetch_actor(httpx_mock, config_system):
|
||||||
"url": "https://example.com/test-actor/view/",
|
"url": "https://example.com/test-actor/view/",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
httpx_mock.add_response(
|
||||||
|
url="https://example.com/test-actor/collections/featured/",
|
||||||
|
json={
|
||||||
|
"type": "Collection",
|
||||||
|
"totalItems": 1,
|
||||||
|
"orderedItems": [
|
||||||
|
{
|
||||||
|
"id": "https://example.com/test-actor/posts/123456789",
|
||||||
|
"type": "Note",
|
||||||
|
"attributedTo": "https://example.com/test-actor/",
|
||||||
|
"content": "<p>Test post</p>",
|
||||||
|
"published": "2022-11-02T00:00:00Z",
|
||||||
|
"to": "as:Public",
|
||||||
|
"url": "https://example.com/test-actor/posts/123456789",
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
identity.fetch_actor()
|
identity.fetch_actor()
|
||||||
|
|
||||||
# Verify the data arrived
|
# Verify the data arrived
|
||||||
|
|
|
@ -30,6 +30,7 @@ from core.uris import (
|
||||||
RelativeAbsoluteUrl,
|
RelativeAbsoluteUrl,
|
||||||
StaticAbsoluteUrl,
|
StaticAbsoluteUrl,
|
||||||
)
|
)
|
||||||
|
from stator.exceptions import TryAgainLater
|
||||||
from stator.models import State, StateField, StateGraph, StatorModel
|
from stator.models import State, StateField, StateGraph, StatorModel
|
||||||
from users.models.domain import Domain
|
from users.models.domain import Domain
|
||||||
from users.models.system_actor import SystemActor
|
from users.models.system_actor import SystemActor
|
||||||
|
@ -740,7 +741,11 @@ class Identity(StatorModel):
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
except (httpx.HTTPError, ssl.SSLCertVerificationError) as ex:
|
except (httpx.HTTPError, ssl.SSLCertVerificationError) as ex:
|
||||||
response = getattr(ex, "response", None)
|
response = getattr(ex, "response", None)
|
||||||
if (
|
if isinstance(ex, httpx.TimeoutException) or (
|
||||||
|
response and response.status_code in [408, 504]
|
||||||
|
):
|
||||||
|
raise TryAgainLater() from ex
|
||||||
|
elif (
|
||||||
response
|
response
|
||||||
and response.status_code < 500
|
and response.status_code < 500
|
||||||
and response.status_code not in [400, 401, 403, 404, 406, 410]
|
and response.status_code not in [400, 401, 403, 404, 406, 410]
|
||||||
|
@ -793,7 +798,11 @@ class Identity(StatorModel):
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
except (httpx.HTTPError, ssl.SSLCertVerificationError) as ex:
|
except (httpx.HTTPError, ssl.SSLCertVerificationError) as ex:
|
||||||
response = getattr(ex, "response", None)
|
response = getattr(ex, "response", None)
|
||||||
if (
|
if isinstance(ex, httpx.TimeoutException) or (
|
||||||
|
response and response.status_code in [408, 504]
|
||||||
|
):
|
||||||
|
raise TryAgainLater() from ex
|
||||||
|
elif (
|
||||||
response
|
response
|
||||||
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]
|
||||||
|
@ -846,6 +855,8 @@ class Identity(StatorModel):
|
||||||
method="get",
|
method="get",
|
||||||
uri=self.actor_uri,
|
uri=self.actor_uri,
|
||||||
)
|
)
|
||||||
|
except httpx.TimeoutException:
|
||||||
|
raise TryAgainLater()
|
||||||
except (httpx.RequestError, ssl.SSLCertVerificationError):
|
except (httpx.RequestError, ssl.SSLCertVerificationError):
|
||||||
return False
|
return False
|
||||||
content_type = response.headers.get("content-type")
|
content_type = response.headers.get("content-type")
|
||||||
|
@ -854,10 +865,11 @@ class Identity(StatorModel):
|
||||||
return False
|
return False
|
||||||
status_code = response.status_code
|
status_code = response.status_code
|
||||||
if status_code >= 400:
|
if status_code >= 400:
|
||||||
|
if status_code in [408, 504]:
|
||||||
|
raise TryAgainLater()
|
||||||
if status_code == 410 and self.pk:
|
if status_code == 410 and self.pk:
|
||||||
# Their account got deleted, so let's do the same.
|
# Their account got deleted, so let's do the same.
|
||||||
Identity.objects.filter(pk=self.pk).delete()
|
Identity.objects.filter(pk=self.pk).delete()
|
||||||
|
|
||||||
if status_code < 500 and status_code not in [401, 403, 404, 406, 410]:
|
if status_code < 500 and status_code not in [401, 403, 404, 406, 410]:
|
||||||
capture_message(
|
capture_message(
|
||||||
f"Client error fetching actor at {self.actor_uri}: {status_code}",
|
f"Client error fetching actor at {self.actor_uri}: {status_code}",
|
||||||
|
@ -923,18 +935,19 @@ class Identity(StatorModel):
|
||||||
)
|
)
|
||||||
# Now go do webfinger with that info to see if we can get a canonical domain
|
# Now go do webfinger with that info to see if we can get a canonical domain
|
||||||
actor_url_parts = urlparse(self.actor_uri)
|
actor_url_parts = urlparse(self.actor_uri)
|
||||||
|
self.domain = Domain.get_remote_domain(actor_url_parts.hostname)
|
||||||
if self.username:
|
if self.username:
|
||||||
webfinger_actor, webfinger_handle = self.fetch_webfinger(
|
try:
|
||||||
f"{self.username}@{actor_url_parts.hostname}"
|
webfinger_actor, webfinger_handle = self.fetch_webfinger(
|
||||||
)
|
f"{self.username}@{actor_url_parts.hostname}"
|
||||||
if webfinger_handle:
|
)
|
||||||
webfinger_username, webfinger_domain = webfinger_handle.split("@")
|
if webfinger_handle:
|
||||||
self.username = webfinger_username
|
webfinger_username, webfinger_domain = webfinger_handle.split("@")
|
||||||
self.domain = Domain.get_remote_domain(webfinger_domain)
|
self.username = webfinger_username
|
||||||
else:
|
self.domain = Domain.get_remote_domain(webfinger_domain)
|
||||||
self.domain = Domain.get_remote_domain(actor_url_parts.hostname)
|
except TryAgainLater:
|
||||||
else:
|
# continue with original domain when webfinger times out
|
||||||
self.domain = Domain.get_remote_domain(actor_url_parts.hostname)
|
pass
|
||||||
# Emojis (we need the domain so we do them here)
|
# Emojis (we need the domain so we do them here)
|
||||||
for tag in get_list(document, "tag"):
|
for tag in get_list(document, "tag"):
|
||||||
if tag["type"].lower() in ["toot:emoji", "emoji"]:
|
if tag["type"].lower() in ["toot:emoji", "emoji"]:
|
||||||
|
|
|
@ -20,6 +20,7 @@ from core.signatures import (
|
||||||
VerificationFormatError,
|
VerificationFormatError,
|
||||||
)
|
)
|
||||||
from core.views import StaticContentView
|
from core.views import StaticContentView
|
||||||
|
from stator.exceptions import TryAgainLater
|
||||||
from takahe import __version__
|
from takahe import __version__
|
||||||
from users.models import Identity, InboxMessage, SystemActor
|
from users.models import Identity, InboxMessage, SystemActor
|
||||||
from users.shortcuts import by_handle_or_404
|
from users.shortcuts import by_handle_or_404
|
||||||
|
@ -150,7 +151,13 @@ class Inbox(View):
|
||||||
|
|
||||||
if not identity.public_key:
|
if not identity.public_key:
|
||||||
# See if we can fetch it right now
|
# See if we can fetch it right now
|
||||||
identity.fetch_actor()
|
try:
|
||||||
|
identity.fetch_actor()
|
||||||
|
except TryAgainLater:
|
||||||
|
exceptions.capture_message(
|
||||||
|
f"Inbox error: timed out fetching actor {document['actor']}"
|
||||||
|
)
|
||||||
|
return HttpResponse(status=504)
|
||||||
|
|
||||||
if not identity.public_key:
|
if not identity.public_key:
|
||||||
exceptions.capture_message(
|
exceptions.capture_message(
|
||||||
|
|
Loading…
Reference in a new issue