I'm debugging ActivityPub integration on a service of my own, https://gath.io. The integration is as follows: I follow a Gathio Actor (an event page) from my personal instance, they accept my request, I become RSVPed to that event, I can then send them a public Note to post messages on that event page. If I'm RSVPed and the event is updated, it will send my personal instance a note with the updated information.
When I tried following a Gathio Actor from my microblog.pub instance, the follow request succeeded. I then tried sending them a Note. Then I updated the even. After those operations, trying to open the Stream or Inbox pages on my microblog.pub instance just shows 'Internal Server Error'.
I found the following errors in the database:
In incoming_activity
:
Traceback (most recent call last):
File "/app/app/incoming_activities.py", line 115, in process_next_incoming_activity
await asyncio.wait_for(
File "/usr/local/lib/python3.11/asyncio/tasks.py", line 479, in wait_for
return fut.result()
^^^^^^^^^^^^
File "/app/app/boxes.py", line 2423, in save_to_inbox
await _handle_create_activity(
File "/app/app/boxes.py", line 1834, in _handle_create_activity
wrapped_object = ap.unwrap_activity(create_activity.ap_object)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/app/activitypub.py", line 376, in unwrap_activity
if get_actor_id(unwrapped_object) != get_actor_id(activity):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/app/activitypub.py", line 313, in get_actor_id
return get_id(activity["actor"])
~~~~~~~~^^^^^^^^^
KeyError: 'actor'
For the ap_object
:
{"@context": ["https://www.w3.org/ns/activitystreams", "https://w3id.org/security/v1"], "id": "https://gath.io/gnKsULvN78i7OzUiD_Eyv/m/57eea1bc8e4cf10b62da522a7b22ad84", "type": "Create", "actor": "https://gath.io/gnKsULvN78i7OzUiD_Eyv", "to": ["https://follow.idiot.sh"], "cc": "https://www.w3.org/ns/activitystreams#Public", "object": {"@context": "https://www.w3.org/ns/activitystreams", "id": "https://gath.io/gnKsULvN78i7OzUiD_Eyv/m/71b00701931f8981d002dfd8e924dfcd", "name": "RSVP to Test!", "type": "Note", "cc": "https://www.w3.org/ns/activitystreams#Public", "content": "<p>This event was just updated with new information.</p><ul><li>the start time changed to Monday 15 May 2023 6:12 am</li><li>the end time changed to Monday 15 May 2023 6:50 am</li></ul> See here: <a href=\"https://gath.io/gnKsULvN78i7OzUiD_Eyv\">https://gath.io/gnKsULvN78i7OzUiD_Eyv</a>"}}
And in outgoing_activity
:
Traceback (most recent call last):
File "/opt/venv/.venv/lib/python3.11/site-packages/anyio/streams/tls.py", line 130, in _call_sslobject_method
result = func(*args)
^^^^^^^^^^^
File "/usr/local/lib/python3.11/ssl.py", line 921, in read
v = self._sslobj.read(len)
^^^^^^^^^^^^^^^^^^^^^^
ssl.SSLWantReadError: The operation did not complete (read) (_ssl.c:2576)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/opt/venv/.venv/lib/python3.11/site-packages/httpcore/backends/asyncio.py", line 33, in read
return await self._stream.receive(max_bytes=max_bytes)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/venv/.venv/lib/python3.11/site-packages/anyio/streams/tls.py", line 195, in receive
data = await self._call_sslobject_method(self._ssl_object.read, max_bytes)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/venv/.venv/lib/python3.11/site-packages/anyio/streams/tls.py", line 137, in _call_sslobject_method
data = await self.transport_stream.receive()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/venv/.venv/lib/python3.11/site-packages/anyio/_backends/_asyncio.py", line 1265, in receive
await self._protocol.read_event.wait()
File "/usr/local/lib/python3.11/asyncio/locks.py", line 213, in wait
await fut
asyncio.exceptions.CancelledError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/opt/venv/.venv/lib/python3.11/site-packages/httpcore/_exceptions.py", line 8, in map_exceptions
yield
File "/opt/venv/.venv/lib/python3.11/site-packages/httpcore/backends/asyncio.py", line 31, in read
with anyio.fail_after(timeout):
File "/opt/venv/.venv/lib/python3.11/site-packages/anyio/_core/_tasks.py", line 118, in __exit__
raise TimeoutError
TimeoutError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/opt/venv/.venv/lib/python3.11/site-packages/httpx/_transports/default.py", line 60, in map_httpcore_exceptions
yield
File "/opt/venv/.venv/lib/python3.11/site-packages/httpx/_transports/default.py", line 353, in handle_async_request
resp = await self._pool.handle_async_request(req)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/venv/.venv/lib/python3.11/site-packages/httpcore/_async/connection_pool.py", line 253, in handle_async_request
raise exc
File "/opt/venv/.venv/lib/python3.11/site-packages/httpcore/_async/connection_pool.py", line 237, in handle_async_request
response = await connection.handle_async_request(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/venv/.venv/lib/python3.11/site-packages/httpcore/_async/connection.py", line 90, in handle_async_request
return await self._connection.handle_async_request(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/venv/.venv/lib/python3.11/site-packages/httpcore/_async/http11.py", line 105, in handle_async_request
raise exc
File "/opt/venv/.venv/lib/python3.11/site-packages/httpcore/_async/http11.py", line 84, in handle_async_request
) = await self._receive_response_headers(**kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/venv/.venv/lib/python3.11/site-packages/httpcore/_async/http11.py", line 148, in _receive_response_headers
event = await self._receive_event(timeout=timeout)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/venv/.venv/lib/python3.11/site-packages/httpcore/_async/http11.py", line 177, in _receive_event
data = await self._network_stream.read(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/venv/.venv/lib/python3.11/site-packages/httpcore/backends/asyncio.py", line 30, in read
with map_exceptions(exc_map):
File "/usr/local/lib/python3.11/contextlib.py", line 155, in __exit__
self.gen.throw(typ, value, traceback)
File "/opt/venv/.venv/lib/python3.11/site-packages/httpcore/_exceptions.py", line 12, in map_exceptions
raise to_exc(exc)
httpcore.ReadTimeout
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/app/app/outgoing_activities.py", line 238, in process_next_outgoing_activity
resp = await ap.post(next_activity.recipient, payload) # type: ignore
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/app/activitypub.py", line 398, in post
resp = await client.post(
^^^^^^^^^^^^^^^^^^
File "/opt/venv/.venv/lib/python3.11/site-packages/httpx/_client.py", line 1842, in post
return await self.request(
^^^^^^^^^^^^^^^^^^^
File "/opt/venv/.venv/lib/python3.11/site-packages/httpx/_client.py", line 1527, in request
return await self.send(request, auth=auth, follow_redirects=follow_redirects)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/venv/.venv/lib/python3.11/site-packages/httpx/_client.py", line 1614, in send
response = await self._send_handling_auth(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/venv/.venv/lib/python3.11/site-packages/httpx/_client.py", line 1642, in _send_handling_auth
response = await self._send_handling_redirects(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/venv/.venv/lib/python3.11/site-packages/httpx/_client.py", line 1679, in _send_handling_redirects
response = await self._send_single_request(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/venv/.venv/lib/python3.11/site-packages/httpx/_client.py", line 1716, in _send_single_request
response = await transport.handle_async_request(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/venv/.venv/lib/python3.11/site-packages/httpx/_transports/default.py", line 352, in handle_async_request
with map_httpcore_exceptions():
File "/usr/local/lib/python3.11/contextlib.py", line 155, in __exit__
self.gen.throw(typ, value, traceback)
File "/opt/venv/.venv/lib/python3.11/site-packages/httpx/_transports/default.py", line 77, in map_httpcore_exceptions
raise mapped_exc(message) from exc
httpx.ReadTimeout
And:
Traceback (most recent call last):
File "/app/app/outgoing_activities.py", line 238, in process_next_outgoing_activity
resp = await ap.post(next_activity.recipient, payload) # type: ignore
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/app/activitypub.py", line 407, in post
resp.raise_for_status()
File "/opt/venv/.venv/lib/python3.11/site-packages/httpx/_models.py", line 736, in raise_for_status
raise HTTPStatusError(message, request=request, response=self)
httpx.HTTPStatusError: Client error '404 Not Found' for url 'https://gath.io/activitypub/inbox'
For more information check: https://httpstatuses.com/404
I don't think /activitypub/inbox
is giving a 404, but I'm happy to assume Gathio is misconfigured so am debugging the implementation.
Is there a way to restore my Stream and Inbox pages on my local instance, or to handle these errors less catastrophically?
I've fixed this by changing
get_actor_id()
inactivitypub.py
to:def get_actor_id(activity: RawObject) -> str: if "attributedTo" in activity: attributed_to = as_list(activity["attributedTo"]) return get_id(attributed_to[0]) else if "actor" in activity: return get_id(activity["actor"]) else: return ""
I'm not sure if this is a kosher way to do this or if it creates issues upstream somewhere, though! But at least it gets me my stream and inbox back.