# Errors

> UCall for Mojo

Every fallible entry point raises `Error` and nothing else, carrying a `Status` shared with the C interface:

```mojo
try:
    server.get["/hello", hello]()
except error:
    if error.status == Status.ALREADY_EXISTS:
        pass  # the template and verb were registered before
    print(error)  # UCall: already-exists [ucall_server_add_http_endpoint]: ...
```

`from ucall import Status, Error`

## Status

Why a call failed, numbered as the library numbers it.

```mojo
struct Status
```

An [`Error`](#Error) never carries [`SUCCESS`](#SUCCESS), and only a [`Deferred`](https://www.unum.cloud/docs/ucall/mojo/requests.md#Deferred) reports [`DEFERRED`](#DEFERRED), until its reply is
final. [`Library.status_name`](https://www.unum.cloud/docs/ucall/mojo/design.md#status_name) spells each one as the library does.

- `SUCCESS` = `Status(Int32(0))`: The call succeeded.
- `DEFERRED` = `Status(Int32(1))`: A submitted call has not finished; the only status that is never final.
- `OUT_OF_MEMORY` = `Status(Int32(2))`: An allocation or reservation could not be satisfied.
- `IO` = `Status(Int32(7))`: A socket or file could not be opened, read, written, or closed.
- `MALFORMED` = `Status(Int32(9))`: The peer supplied bytes that cannot be decoded as the expected protocol.
- `INTERNAL` = `Status(Int32(10))`: The library violated its contract, which points at a defect.
- `OVERFLOW` = `Status(Int32(11))`: The requested size exceeds the representable range.
- `UNINITIALIZED` = `Status(Int32(12))`: The call needs a handle that was never initialized.
- `CONTENDED` = `Status(Int32(14))`: The call was refused rather than waited for, like a submission to a full client.
- `UNSUPPORTED` = `Status(Int32(16))`: The build, backend, or machine does not implement the requested feature.
- `INVALID_ARGUMENT` = `Status(Int32(17))`: An argument is missing, out of range, or contradicts another argument.
- `NOT_FOUND` = `Status(Int32(18))`: The requested endpoint, header, or parameter does not exist.
- `ALREADY_EXISTS` = `Status(Int32(19))`: An endpoint with the same template and verb is already registered, or a request was answered.
- `CONNECTION_FAILED` = `Status(Int32(20))`: DNS lookup or connection establishment failed.
- `CONNECTION_CLOSED` = `Status(Int32(21))`: The connection closed before the exchange completed.
- `TIMEOUT` = `Status(Int32(22))`: The operation exceeded its time budget.
- `HANDSHAKE_FAILED` = `Status(Int32(23))`: The Noise handshake failed to authenticate or agree on keys.
- `PEER_REJECTED` = `Status(Int32(24))`: The peer authorizer declined the authenticated static key.
- `WOULD_BLOCK` = `Status(Int32(25))`: Nothing was ready: a nonblocking poll, a pull with no body bytes yet, or a lagging stream peer.
- `LIBRARY_MISSING` = `Status(Int32(-1))`: Nothing to `dlopen`; the binding's own.
- `SYMBOL_MISSING` = `Status(Int32(-2))`: The library loaded but does not export a symbol the binding needs; the binding's own.
- `VERSION_MISMATCH` = `Status(Int32(-3))`: The library loaded but reports another major version than the binding's; the binding's own.
- `code` `Int32`: The raw `ucall_status_t` value, kept even when this build does not name it.

Conforms to: `Copyable`, `Deinitable`, `Equatable`, `ImplicitlyCopyable`, `Movable`, `RegisterPassable`, `TrivialRegisterPassable`

## of

Lifts a raw `ucall_status_t`, keeping an unnamed one rather than guessing.

```mojo
def of(code: Int32) -> Self
```

- `code`: Whatever the C call reported, named by this build or not.

## Error

What went wrong inside the library, and which entry point it was about.

```mojo
struct Error
```

- `status` `Status`: Which class of failure the library reported.
- `detail` `StaticString`: The entry point it was about, for a reader rather than for a branch.
- `message` `Optional[Pointer[Scalar[_c_char_dtype()], ImmUntrackedOrigin]]`: The library's own static message, or `None` when it carried none.
- `name` `Optional[Pointer[Scalar[_c_char_dtype()], ImmUntrackedOrigin]]`: The library's spelling of [`status`](https://www.unum.cloud/docs/ucall/mojo/requests.md#status) from `ucall_status_name`, or `None` where none named it.
- `library` `Optional[Library]`: The library `message` and `name` live in, kept mapped for as long as the error is; Mojo would otherwise unload it at the last handle's last use, while the error is still being read.

Conforms to: `Copyable`, `Deinitable`, `ImplicitlyCopyable`, `Movable`, `Writable`

## __init__

A failure the binding caught before the library could name it.

```mojo
def __init__(out self, status: Status, detail: StringSpan[ImmStaticOrigin])
```

- `status`: Which class of failure it is.
- `detail`: The entry point or binding type it was about.

## write_to

Writes the status name, the entry point, and the library's own message together.

```mojo
def write_to(self, mut writer: T)
```

- `writer` (mut): The sink the message is appended to.

