Errors
Two things to check on every response: the HTTP status, and accepted on a send. A refused
message returns 200, so status alone is not enough.
Shape
{
"success": false,
"message": "Your wallet balance is too low to send this message. Add funds and try again."
}message is written to be shown to a person as-is. It never contains a stack
trace, an internal identifier or anything about our infrastructure.
Status codes
Refusals that arrive as 400
These are setup problems rather than request problems, and each names what to fix:
Rejections on a 200
When accepted is false, the message reached the network and was refused.
message says what a customer can do about it, and there are only two shapes:
- The number is the problem. "That mobile number does not look valid." Check it; retrying the same number will not help.
- The problem is on our side. "This message could not be sent right now and has not been charged." Nothing you can fix, nothing charged, and our team is notified. Retrying shortly is reasonable; retrying in a tight loop is not.
Writing retry logic
Branch on the status class first
4xx other than 429 and 402 means stop. 429, 500 and 503 mean retry.
Then branch on accepted
A 200 with
accepted: falseis a settled outcome for that message. Retrying sends a second message rather than fixing the first.Back off exponentially, with a cap
A fixed one-second retry from many workers at once is the same as no retry logic at all.
Give up and record
After a few attempts, store the
message_idif you have one and move on. A human looking at a list of failed ids is more useful than a queue retrying forever.