Errors that guide you
Every failure returns a class, an exit code, and the decision it implies.
“Something went wrong” is not actionable. An agent has four possible reactions to a failure — retry, fix the request, re-establish something, or give up — and those are four different situations. So every failure carries a stable code and a stable exit status, and the table below is grouped by the reaction rather than sorted by number.
{
"error": {
"code": "invalid_region",
"message": "region 100,200,800,600 does not fit inside 1920x1080"
}
}Branch on code. The message is for a human reading logs, and is allowed to change; the code is not.
The request is wrong
The request itself is wrong. Retrying will fail identically; something about the arguments or the geometry needs to change.
| Exit | Code | Meaning |
|---|---|---|
| 2 | invalid_arguments | Unparsable or contradictory arguments. |
| 4 | invalid_region | Region is malformed, zero sized, or out of bounds. |
| 5 | window_not_found | The requested window does not exist. |
| 7 | resize_failed | The requested resize could not be performed. |
| 10 | incompatible_frames | The two frames cannot be compared. |
| 12 | image_load_failed | An input image could not be read or decoded. |
| 15 | invalid_duration | A duration was zero, negative, or unparsable. |
| 25 | invalid_presentation_policy | The presentation policy is malformed or self-contradictory. |
| 26 | payload_budget_exceeded | The required views cannot fit in the requested budget, even at their floors. |
Something outside the request changed
Something outside the request changed. A retry may work, and a retry after re-establishing a session usually will.
| Exit | Code | Meaning |
|---|---|---|
| 3 | display_unavailable | The X11 display could not be opened. |
| 6 | capture_failed | The backend could not produce a frame. |
| 9 | output_failed | Writing the result failed. |
| 13 | geometry_changed | The observed target changed shape or moved. |
| 14 | target_lost | The observed target disappeared. |
The session is in the wrong state
The session's state does not permit this. Create a new session, or wait for the one you have to become free.
| Exit | Code | Meaning |
|---|---|---|
| 17 | session_not_found | The session is not registered — closed, or the service restarted. |
| 18 | session_busy | The session is running an observation; a second one, or a close, was refused. |
| 19 | session_closed | The session has been closed. |
| 20 | frame_not_available | The requested frame ID is not retained, or was never captured. |
| 21 | no_frame_available | The session has not captured any frame yet. |
The service refused or failed
The service could not do the work: absent, overloaded, or speaking a protocol the client does not understand.
| Exit | Code | Meaning |
|---|---|---|
| 22 | service_unavailable | No `eensh serve` could be reached at the socket path. |
| 23 | service_protocol_error | The service could not decode a request, or a protocol version was refused. |
| 24 | service_overloaded | The service refused work to preserve freshness. |
A bug in the tool
A bug. The request was well-formed and the environment was fine, so this should not have happened.
| Exit | Code | Meaning |
|---|---|---|
| 1 | internal_error | Unexpected internal failure. |
| 8 | encode_failed | PNG or JPEG encoding failed. |
| 11 | comparison_failed | The comparison could not be performed. |
| 16 | observation_failed | The observation could not be performed. |
Not an error
Nothing failed. The operation completed and the condition simply did not occur.
| Exit | Code | Meaning |
|---|---|---|
| 100 | — | Timeout: the observation ran, the condition did not occur. |
The two cases that are not errors at all
Two situations look like failures and are deliberately not ones. Both are worth knowing before you write error handling, because treating either as an error is the most common mistake in a first integration.
Errors cross the process boundary unchanged
A service error is mapped back to the status it would have had on the standalone path. A frame_not_available from eensh serve exits 20, exactly as the equivalent standalone command would. The table above stays the single source of truth whether or not a service is involved.