Results and errors
In AEL, the Agent Engineering Language, a value that may be missing will be an Option, and an operation that can fail will return a Result. There will be no null value and no exceptions: an error will be an ordinary typed value that your code handles, passes on or turns into another error.
Status
Planned for AEL Beta 0.0.1. AEL is not available yet.
Option
| Variant | Meaning |
|---|---|
Option::Some(value) | A value of type T is present. |
Option::None | No value. Option::None is itself a value, written without parentheses. |
Use Option<T> for a setting that may be left out, a search that may find nothing, or a field that is filled in later.
fn first_positive(values: [i32; 3]) -> Option<i32> {
let mut i: u32 = 0;
while i < 3 {
if values[i] > 0 {
return Option::Some(values[i]);
}
i = i + 1;
}
return Option::None;
}
Result
| Variant | Meaning |
|---|---|
Result::Ok(value) | The operation succeeded with a value of type T. |
Result::Err(error) | The operation failed with an error of type E. |
An operation that succeeds without a value will return Result<(), E>, and its success will be Result::Ok(()).
Handling an error
You will take a Result apart with match, which will have to handle both variants. To pass an error on, return it from your own function; to replace it, return a different error.
enum LookupError {
NotFound,
Invalid(u16),
}
fn discount(code: u16) -> Result<u32, LookupError> {
if code == 0 {
return Result::Err(LookupError::Invalid(code));
}
if code > 500 {
return Result::Err(LookupError::NotFound);
}
return Result::Ok(10);
}
fn price_after(price: u32, code: u16) -> Result<u32, LookupError> {
match discount(code) {
Result::Ok(percent) => {
return Result::Ok(price - price / 100 * percent);
}
Result::Err(error) => {
return Result::Err(error);
}
}
}
- An error type will usually be an enum of your own, and its variants will be able to carry values, such as the code in
Invalid(u16). - Nothing will be thrown and nothing will be retried unless your code retries it.
- Binding a value in a
matcharm will move it out of the matched value; see Ownership.
Built-in error types
Four error types will be built in. Each will be an enum whose values copy like integers.
| Type | Variants | Returned by |
|---|---|---|
CapacityError | Full | Appending text that does not fit. |
IndexError | OutOfBounds | Removing a list value at an index that does not exist; reading a byte of text past its end. |
CastError | OutOfRange | Converting an integer to a type it does not fit. |
StringError | InvalidUtf8, Full | Making text from bytes that are not valid UTF-8, or do not fit. |
Text and collections and Numbers list the operations.
Errors that give your value back
When an operation cannot take a value you pass it, the error will hand the value back, so it is never lost and never owned twice:
- adding to a full list will return
Result<(), T>, and the error will hold your value; - sending a message to a full or closed mailbox will return the message to you; see Concurrency.
In both cases the collection or mailbox will stay exactly as it was: nothing will be half-added.
Errors from the rest of the library
Operations that reach outside the program will return typed results that keep different failures apart, so your code can react to each:
- Models: an unsupported parameter, input or capability, a missing binding or credential, an input that is too large, an incomplete output, and usage that could not be counted. See Model client.
- HTTP: a connection or TLS failure, a timeout, a cancellation, a body over its limit. See HTTP client.
- Programs you run: a non-zero exit, a timeout, a failure to start, output that could not be read, a cancellation, a resource limit. See Files and processes.
When a failure leaves it unknown whether an effect outside the program happened, such as a payment sent before a connection dropped, the result will say the effect is uncertain rather than report success or failure. Your code will decide how to reconcile it; AEL will not repeat such an operation on its own.
Errors, panics and diagnostics
| Kind | When | What will happen |
|---|---|---|
| Diagnostic | You check or build your code. | Nothing runs until you fix the source. |
Result error | An operation fails in a way your program expects. | The operation returns Result::Err, which you handle. |
| Panic | A defect: an overflow, a division by zero, an index out of range. | The program stops with a failure report. A panic is never caught as a Result. |
Errors and checked arithmetic describes panics, and Concurrency how agents recover from faults.