Designing an Interface to Call
Your Error Message Is Read by a Program First and a Human Second, and Almost Every Interface Gets That Order Backwards
Last timeChoosing the Operations
Designing a failure response a caller can branch on: the one field that has to be stable, the retryable question, the four classes of failure, and what must never appear in the text.
Two audiences, in order
Somebody calls your interface and it fails. Two things now read the response.
A program reads it first. It needs to decide, in microseconds and without any
judgement, whether to retry, whether to fall back, whether to log loudly, and
whether to show the user something. It does this by matching on a value.
A person reads it second, hours later, in a log, trying to work out what
happened. They need a sentence.
Most interfaces supply the sentence and leave the program to match on it, which
is why so much caller code contains a comparison against a string of prose.
That code breaks the day somebody improves the wording, and improving the
wording is exactly the kind of change nobody thinks to announce.
status 422
code: order_item_out_of_stock
retryable: false
title: not enough stock to fulfil this order
detail: 3 units of the requested item are available, 5 were asked for
field: items.2.quantity
request_id: 0f3a9c21-7b44-4e2d-9a18-6c0e5d7b1f42
documentation: errors/order-item-out-of-stock
what each line is for
code the program matches on this, and it never changes
retryable the program decides whether to try again
title the person reads this, and it may be reworded freely
detail the person diagnoses with this
field the interface can point at the input directly
request_id the caller quotes this to you and you find the traceThe code is the contract. Choose it carefully, make it specific, and never
reuse one for a different situation. A caller handling the stock case wants to
offer the customer a smaller quantity, and they cannot do that if the same code
also covers six other kinds of rejection.
Retry, or fix
The second field is the most valuable one and the least often present.
A caller who receives a failure has exactly two useful questions. Could this
have succeeded if I tried again, and if not, what do I change. They cannot
answer the first from the outside, because a temporary capacity problem and a
permanently malformed request can look identical from where they are standing.
The lesson stops here
4 more paragraphs to go
You have read the opening. The rest of the argument, the problems that check whether it landed, and the lines worth keeping at the end all come with a plan.
The first lesson of every course in the library reads the whole way through, free, so you can see exactly what the rest of them are.
See the planThe contentsThis is the reading half
Starting the course gives you your own copy of it. Every idea on every page has problems standing under it, marked with a reason rather than a tick, and any sentence you do not believe can be opened and argued with. None of that can happen on a page nobody owns.
The contents