A program meets situations its author did not plan for. A database connection that is missing in one environment. A request that arrives at an endpoint nobody switched on. A message with no signature. In each of those moments the code has to choose between going on and stopping, and I now write the choice down on purpose.

The first place is the entry point of the whole app. If the connection to the database is missing, every page returns a 503 and a short message, with one exception: the public privacy page, which holds only text. Earlier, a missing connection skipped the login check and served the pages anyway. They showed empty lists, because there was nothing to read, but the pattern is wrong. A configuration mistake in a preview environment should produce an outage, and it should not produce an open door.

The second place is the endpoint for incoming WhatsApp messages. It is switched off by default. Until an owner turns it on, the endpoint answers 404 and does nothing, which was the review's finding when it first sent an empty request and got a 200 instead. A thing that is off should look off from the outside.

The third place is the signature. When the endpoint is on, each request must carry a signature made with a shared secret. If the secret is not configured, or the signature is missing or wrong, the message is dropped. In an earlier version a check existed on paper and nothing called it, so an unsigned message with the word STOP or YES would have changed a customer's status. Now there is no path from an unsigned request to a database write.

Sending follows the same idea. The default mode is a simulation that records what would have been sent and sends nothing. Moving to real links is a conscious change in settings made by the owner, and the app never offers automatic sending.

A rule I use when I write this kind of code: for every external input, I ask what happens if it is absent and what happens if it is wrong, and I want the answer to be written in the code and not left to a default value. Stopping in the wrong moment costs a minute of annoyance. Continuing in the wrong moment can cost a customer's trust.

Disclosure: drafted with a local AI model, then reviewed and approved by me. Originally published at https://bbal-blog.kairo-app.workers.dev/failing-closed-three-places-where-my-app-says-no-when-unsure/