DEV Community

Emma
Emma

Posted on Originally published at supercrontab.com

I wanted a webhook receiver that could be slow and flaky on purpose, so I made one

There are plenty of "paste this URL and see what arrives" webhook testers, and they're fine for the first half of the job: is my service sending the right headers and body? What none of them did for me was the second half: what does my service do when the receiver is having a bad day? Times out. Returns 500. Works four times out of five.

That second half is where the expensive bugs live. Duplicate orders because a retry fired after a slow 200. Alerts that never went off because nobody tested the 500 path. So I built a receiver that can misbehave on request.

The boring half: see what you sent

You create an endpoint (takes about a minute: https://supercrontab.com/webhook-tester), get a URL like https://yourslug.supercrontab.com/, point your service at it. Every request shows up in a log with the method, path, headers, body (up to 16 KB), the caller's IP and the status you answered with. Authorization, Cookie and API key headers are redacted in the log, on purpose, because I didn't want to run a service that stores other people's tokens.

Sub-paths and trailing slashes work, so /orders/42/ reaches the same endpoint and you see the path in the log.

The useful half: make it misbehave

Same form, a few more fields:

  • status code, so 202 for "accepted" or 500 when you want to see your alerting fire
  • delay in milliseconds, to find out whether your sender times out and what it does after
  • error rate, so one call in five fails, which is what a flaky partner actually looks like
  • auth: Basic, Bearer, an API key header, or an HMAC-SHA256 signature over the body

My default setup is "202, 3 seconds, 10% errors". If your sender gets through a day of that with correct retries and no duplicated side effects, you're in decent shape.

The HMAC one caught a real bug for me: I was signing the pretty-printed JSON and sending the compact one. The endpoint answered 401 and I stared at it for ten minutes before I understood why.

Closing the loop

The same account has a cron scheduler, so you can schedule a job to call your endpoint every 15 minutes with a Bearer token and watch the job's run history and the endpoint's log agree with each other. I leave one running as a canary.

Why it needs an account

Anonymous receivers get used as drop boxes for stuff nobody should be storing. Tying every receiver to an account keeps the logs private, keeps the service clean, and lets you delete everything when you're done. The free plan has 3 endpoints, 30 requests a minute, 500 a day, and doesn't expire.

If you want to try only the response side first, without an account, there are 112 static demo endpoints (8 formats x 14 status codes) at https://supercrontab.com/mock, for example https://demo-json-503.supercrontab.com/.

Two things I still want: replaying a logged request to another URL, and exporting a log as a HAR. If you'd use either, tell me which first.

Top comments (1)

Collapse
 
raju_dandigam profile image
Raju Dandigam

@emma_teelylabs, controllable delay and failure rates cover the expensive half of webhook testing that capture-only tools miss. Before HAR replay, I’d be especially interested in deterministic fault sequences keyed by an idempotency key: for example, “commit the first request, close the connection before the response, then return 200 on retry.” That reproduces duplicate-side-effect bugs more reliably than a random 10% failure rate and makes the case suitable for regression tests. Would you expose scripted per-endpoint sequences as a third mode beside fixed and probabilistic responses?