Failing Gracefully
I’m talking about how software can fail gracefully and how it will be important to the FediVerse to require your software to have nice failure behavior. As an example, you folks on Mastodon and possible other platforms, you might only see one paragraph followed by a link. This is what I would call “pretending everything is ok, while it isn’t”. You’ll miss all the content, if you don’t click on the link.
The format of this post is that, I first do two exhibits of behavior and then actually come to the content.
Exhibit 1: This blog and its posts
I want to do the example from the introduction in some more details. Let’s look at a post https://blog.mymath.rocks/2023-03-16/Link_header_for_better_interoperability_with_Mastodon, and do some cases.
- You click on the link, you see a page similar to this one, with light blue background and text, and a code block containing a HTML link tag.
- You search for the above link on Mastodon. The result is the following
Helge @helge@mymath.rocks
Link header for better interoperability with Mastodon
One of my goals with this blog is to make it into a first class ActivityPub citizen. Today, I want to talk about how to make it so that Mastodon can lookup the blog post, when pasting the URL in its search box. I mostly write this down, to have the behavior documented somewhere.
https://blog.mymath.rocks/2023-03-16/L…
- You get smart on me, extract the link header that is described in the post and open it in your webbrowser. The link is https://mymath.rocks/objects/4b3dc14c-666f-4fe1-8dc6-ec2d18797779. A redirect should happen, leading back to the HTML page.
- You get smarter on me, and request the underlying object, i.e.
curl https://mymath.rocks/objects/4b3dc14c-666f-4fe1-8dc6-ec2d18797779 -H accept:applicaton/activity+json
Now you get an unauthorized answer. Due to bovine only handing out the full objects to HTTP signed requests.
- You decide to continue playing the game and sign the request. Have fun! The result is the following heap of json:
{
"@context": [
"https://www.w3.org/ns/activitystreams",
{
"conversation": "ostatus:conversation",
"inReplyToAtomUri": "ostatus:inReplyToAtomUri",
"ostatus": "http://ostatus.org#"
}
],
"attributedTo": "https://mymath.rocks/endpoints/SYn3cl_N4HAPfPHgo2x37XunLEmhV9LnxCggcYwyec0",
"cc": "https://mymath.rocks/endpoints/30zoCe7haKBEFolH4rbAmKj-t9_bG0c2X2kMQkJk5qY",
"content": "<h1>Link header for better interoperability with Mastodon</h1>\n<p>One of my goals with this blog is to make it into a first class ActivityPub citizen. Today, I want to talk about how to make it so that Mastodon can lookup the blog post, when pasting the URL in its search box. I mostly write this down, to have the behavior documented somewhere.</p>\n<h2>The working solution</h2>\n<p>Basically, ....</p>",
"id": "https://mymath.rocks/objects/4b3dc14c-666f-4fe1-8dc6-ec2d18797779",
"name": "Link header for better interoperability with Mastodon",
"published": "2023-03-16T20:03:51Z",
"source": {
"content": "# Link header for better interoperability with Mastodon\n\nOne of my goals with this blog is to make it into a first class ActivityPub citizen...",
"mediaType": "text/markdown"
},
"summary": "One of my goals with this blog is to make it into a first class ActivityPub citizen. Today, I want to talk about how to make it so that Mastodon can lookup the blog post, when pasting the URL in its search box. I mostly write this down, to have the behavior documented somewhere.",
"to": "as:Public",
"type": "Article",
"url": "https://blog.mymath.rocks/2023-03-16/Link_header_for_better_interoperability_with_Mastodon"
}
Now, I wanted to critize Mastodon’s behavior. Let’s first descibe what it does. Basically, when Mastodon sees an object of type Article
, it gets transformed according to the following pattern
name
summary
url
You can check with the above example. The problem with this is, that it might be non obvious to the casual user that Mastodon is dismissing most of the content of the object. This will in particular become a problem when people start using more complicated object types.
Exercise: Think about how you would change Mastodon’s behavior.
Exhibit 2: Bovine’s behavior
I already talked about that Bovine redirects to web pages for certain objects. The criterion is that the object has an url
property. I have taking this property me “If you look at me in a webbrowser, you should look at this”. I sometimes talk about visibility of objects. I would call the above behavior web visible, this means in terms of ActivityPub, that the object is addressed to Public
and that it has an url
property.
So what, do we do for an object without an url? Let’s do a somewhat silly example: https://mymath.rocks/objects/a8d23e75-88a1-4f77-a85c-aa58f245ddbf. If you open this in a webbrowser, you see a page with a yellow background, some commenting text and the important information
Object Information
Id: https://mymath.rocks/objects/a8d23e75-88a1-4f77-a85c-aa58f245ddbf
Type: Like
Summary: 🐮
This means that this was actually a Like activity, which make perfectly fine objects as far as Bovine is considered. Looking this object up on Mastodon leads to nothing found. Finally, the same authentication logic applies as before, if you manage to sign the request the result would be
{
"@context": "https://www.w3.org/ns/activitystreams",
"actor": "https://mymath.rocks/endpoints/SYn3cl_N4HAPfPHgo2x37XunLEmhV9LnxCggcYwyec0",
"cc": "as:Public",
"content": "\ud83d\udc2e",
"id": "https://mymath.rocks/objects/a8d23e75-88a1-4f77-a85c-aa58f245ddbf",
"object": "https://social.coop/users/smallcircles/statuses/110071688629088597",
"published": "2023-03-23T16:50:32.185Z",
"to": "https://social.coop/users/smallcircles",
"type": "Like"
}
I’m not sure what behavior, I would expect here. However, I believe that these two cases explain that this is a topic, that should be discussed as different FediVerse applications might interpret content differently.
My request to the FediVerse
First, I wrote this post, to get more people to consider these issues. Without appropriate fallback behavior, FediVerse applications will be limited to be tools for their own type of content.
If you feel like working out a solution, discuss it on SocialHub and then submit it as a FEP.
One solution, I personally like and am following with bovine is to separate ActivityPub between a more generic server implementation working with several ActivityPub Client applications. We have already talked about this blog, it is actually a Client application that does two things:
- Take a Markdown file and render it as a blog post.
- Listen for comments and display them below the post.
There are some missing pieces like allowing me to include pictures and d3.js charts, but that is mostly on how to upload content to it. I actually use another ActivityPub Client to interact with comments on this blog.
The point here is if one splits the server at the right spot, one can have very specific clients, e.g. this blog, and still be able to interact with everyone on the FediVerse.