Errors, and what to do about each
Every error the SDK raises about a record, the door, the evidence, an exhibit or the account is a
TallwrightError, and every error says which record it is about (record_id) and, when an answer arrived
at all, the door's HTTP status (status). An argument it cannot use is refused before anything is written
or sent, with the TypeError or ValueError Python raises for such a thing: content without one byte
form, an action_type, actor_authority, timestamp, record_id or customer_ref it does not take, an
address or a key it will not send to, a receipt Receipt.read cannot read. No message carries the
content, the salt or a key: a message is the thing you paste into a ticket.
There are two kinds, and they call for opposite things.
Send it again: NotConfirmed
No receipt came back. The door was unreachable, the answer was lost, something in between answered instead of the door, or the key or the account was wrong. The record is pending in your evidence, and whether the door holds it is not known.
- Do:
client.resend(record_id)sends the same line again, byte for byte. A record the door already holds is recognised by itsrecord_idand answeredalready_held, never written twice.client.pending()lists what is pending;tallwright-cloud resenddoes the same from a shell. - Do not: capture it again. A new capture is a new record with a new salt, and an answer that was only lost becomes the same event recorded twice.
- In the background (
submit), the SDK sends again on its own, with a growing pause, for as long as the answer decides nothing (a lost answer, or 408, 425, 429, 500, 502, 503 or 504), and tellson_problemonce per streak of failures. It does the same with every other answer that is neither a receipt, nor the door's refusal, nor one of the two stops below: a 404 (an address that does not lead to the door), a 413 or a 501 is sent again too, without end, so a streakon_problemwas told of and that does not end is yours to look at.
Two kinds of NotConfirmed stop the background sending for that client until a person acts, because
sending again cannot help:
Unauthorized(401): the key is not one the door holds. Put the right key in place, thenresend(record_id, adopt=True): a pending record stays bound to the key it was written under, and a client holding another key sends it only when it adopts it, which is your statement that this key belongs to the same Environment. The same call sends a record pending under a key the Environment has since replaced. From a shell,tallwright-cloud pending --all-keyslists it andtallwright-cloud resend --adopt IDsends it.AccountClosed(403): the account behind the key is closed, and the answer says since when. Nothing is recorded until it is reopened; thenclient.resend_pending()sends what is pending, each record once. The log is still there and still exports.
Do not send it again: Refused
The door read the line and refused what it says, in its own sentence. The record is not pending, and the same line will never be accepted.
Refused(400,line N is not a usable record): a field the door does not take, or a value it cannot use. The sentence names which. Fix the call, and record the event again.RecordIdConflict(409): the log holds a different record under thisrecord_id. On a first send that is another event: send yours under its own name. On a resend, whether that record is an earlier send of this same line cannot be told from the answer; an exhibit of the record shows which.
A refusal without the door's own sentence (a proxy's error page, say) is never taken for a Refused: the
record stays pending, and is a NotConfirmed.
The door lost what it confirmed: LostByTheDoor
A receipt showed that the door's log no longer holds records it had confirmed: it puts a new record after the record one of them followed, and a log that only grows has one record there. The cause is on the door's side, its log put back to an earlier state after its last anchor (a restore, or a power cut that took it back cleanly), and nothing there can tell. Your evidence can, because it keeps every receipt.
- It is not raised: the capture whose receipt showed it was recorded. It goes to
on_problemand thetallwright_cloudlogger, andrecord_idsnames every record that was lost. - Do:
client.resend(record_id)for each, orclient.resend_pending(). Each is pending again, and its line and its pair are still in your evidence, so it is recorded anew, at a new leaf. The receipt that no longer stands stays beside it, andlost.jsonnames the receipt that took it back. - Tell the door's operator which records were lost.
- Not seen this way: a log put back to empty, or past records whose receipts this evidence does not hold.
The evidence: EvidenceError
The store that keeps your evidence could not do its part: a directory that cannot be written, a file
system that ends with its container, a bucket that does not honour "create only if absent". When it fails
before sending, nothing was sent. tallwright-cloud doctor says what stands in the way.
Exhibits: ExhibitError
No exhibit was handed over, and nothing was filed.
ExhibitNotReady(409): the door could not build the exhibit now, and says why: most often, no witness has covered the record yet. Nothing was used by asking. Ask again after the next anchor run; a link opens again until it expires.LinkSpent(410): the one-time link was used already. Ask the backoffice for a new one.ExportKeyRefused(401): the exhibit door holds no such export key: never issued, replaced, or withdrawn. The backoffice issues a new one.
The account API: AccountError
The account API refused or could not complete a request, in its own sentence where it gave one.
EnvironmentExists(409): an open Environment for thiscustomer_refexists, and nothing was made. Whenmaybe_oursis true, an earlier attempt of the same call may have made it and its answer was lost:account.new_key(environment.id)gives it a key you hold. Acreateissued again later is a new call, and saysmaybe_oursfalse even when its own lost first call made the Environment: for acustomer_refyou issued, the samenew_keygives it a key you hold.
Every answer of the recording door
For code that speaks HTTP itself, the whole table is in Cloud Proof over HTTP. In short:
- Recorded: 200, with a receipt per line.
- Not recorded, send the same bytes again: 429 (after the seconds in
Retry-After), 500, 502, 503, 504, a lost answer, and any 400 that is notline N is not a usable record. - Not recorded, sending again cannot help: 400
line N is not a usable record, 409, 413 (split the batch), 501 (send a Content-Length), 401 (the key), 403 (the account), 404 (the address). - Not recorded until the operator repairs the log: 507. A write before yours was cut short, by a full disk for example. The record stays pending; send the same bytes once the log is repaired.