DEV Community

LazyRelay
LazyRelay

Posted on

Four ways "the post succeeded" can be a lie

I build a tool that schedules social posts. This week I added four new places to publish: WordPress, dev.to, Hashnode and Lemmy. Then I had each adapter reviewed by someone who did not write it. The most useful findings were all the same kind of bug: the code said "published" when it had only proven "the server answered".

Here are four ways that happens.

1. A 200 is not the post

My first version of the read-back check fetched the public page and treated HTTP 200 as "live". That passes for a maintenance page, a parked domain, a "coming soon" plugin, or a password-protected post whose public page is just a password form. All of them answer 200.

The fix: read a small part of the page and require the post's title or its slug to appear in it. If the proof cannot name the post, it is not proof.

2. The URL in the response is not yours to trust

The read-back used the link the platform sent back. On a blog with a custom domain, that domain is controlled by the customer. It can answer with a redirect to an address inside your own network, and a naive fetch follows it and reports success.

The fix: do not follow redirects blindly. Check every hop, require the final host to match the expected host, and never send credentials past the first host.

3. A timeout does not mean "it did not happen"

If the create request times out, the platform may still have created the post. A scheduler that retries now publishes it twice, in public.

The fix: after a network error, look for a post with the same title from the last few minutes before you report a failure, and if you cannot tell, say so instead of retrying blindly.

4. "Saved as a draft" is not a failure

Some customers choose to save a draft on the platform instead of publishing. A read-back that insists the post is public will call that a failure and retry it until it gives up. A draft that exists exactly where the customer asked for it is a finished job. It just should not be counted as published.

The fix: give "saved as a draft" its own ending, so it is never retried and never inflates a "verified live" number.

The pattern

In all four, the code checked the easy thing (did the server answer?) instead of the thing I actually care about (can a stranger see this post?). Whenever a system reports success, ask what it actually observed, and whether that observation could be true while the post is not live.

I use this idea in LazyRelay, the scheduler I am building: after every post it reads the platform back to confirm the post is really there. You can look at it at https://lazyrelay.com.

What is the strangest "success" you have seen an API report?

Top comments (0)