Result records that a function can either return a value or one of these
errors.
This gives each failure a stable name. Callers can respond to the error without
parsing its message.
Declare an expected error
Declare each kind of failure witherror. Add fields when the caller needs
details about what went wrong.
- Forst
- Generated Go
error interface.
Start with a small error
An error can carry only the data needed to explain or handle the failure.- Forst
- Generated Go
validatePositive returns NotPositive when the check fails. Generated Go
returns the same error as an ordinary Go error.
Return a value or an error
A function that can fail returnsResult(Success, Failure). The first type is
the successful value. The second type is the error. The failure type must belong
to the Error family.
Forst can infer this return type when ensure introduces a failure path.
- Forst
- Generated Go
okInt can fail, so Forst infers Result(Int, Error). The caller
uses ensure x is Ok() before using the successful value.
Ok() and Err() identify the two sides of a Result during is and
ensure checks. They are currently checks. General Ok(value) and
Err(error) constructors are still in development.
Return a specific error with ensure
Useensure condition or error when a failed check should return a known error.
The function stops at that point and gives the error to its caller.
- Forst
- Generated Go
avail to contain a successful value. The second
check returns InsufficientStock with details that the caller can use.
Let Forst infer the return type
Forst looks at three places when a function has no declared return type.- Each explicit
return - Each
ensurethat can fail - The final expression in the function body
return.
- Forst
- Generated Go
g returns Result(Int, Error). The final call to g() means that f
returns the same type. Generated Go contains return g().
Use an explicit return whenever it makes the intent easier to see.
Handle Go functions with several returns
Go functions often return a value and an error. Forst preserves all returned values when you capture the call in one variable. The resulting type isTuple(T₁…Tₙ).
Split the values and check the error when your Forst function should return a
Result.
Result and Tuple stay separate
The two types make different promises. AResult contains one outcome. It is
either a success or a failure. A Tuple preserves every returned position, and
several positions may contain meaningful values at the same time.
Problems caused by mixing them
Result means that you get a value or an error. Some calls can return both.
For example, a read can return its final bytes together with an end of input
signal. The bytes still need to be processed.
Forst cannot learn this behavior from the return types. A pair containing a
value and an error looks the same in both cases. Keeping a list of special calls
would miss new packages and functions.
Forst therefore never turns several return values into a Result
automatically. This keeps Ok() and Err() trustworthy. Ok() always means
that there is no error. Err() always means that there is no success value.
How Forst keeps the meaning clear
- A call with several returns always becomes a
Tuplewhen captured in one value. Every returned value stays available. - A
Resultcomes from a function with exclusive success and failure paths.returnandensuremake those paths explicit. - Conversion between
TupleandResultis unavailable.Ok()andErr()only apply toResult. - When you know a call has exclusive outcomes, split its values and use
ensure !err or errbefore returning the success value. - The rule applies to every package. It needs no catalog or project setting.
Result reliable for narrowing and for generated client types.
If a call with several returns is the final expression of an inferred function,
the function also returns a Tuple. Split the values as shown above when you
want a Result.
For calls used only for side effects, prefer Forst println or print. A
Provider contract method can also declare an explicit
return type.
Use errors from TypeScript
Generated TypeScript clients can expose error payloads as tagged shapes. This part of the client API is still evolving. Generate the client withforst generate and see Generate client types
for the current output.
How this compares with Go
In Go, you usually declare a struct and add anError() method. Forst’s
error Name { … } declaration creates both parts from one declaration. The
generated result remains an ordinary Go error.
Current limits
Named errors andResult are experimental. Check the
roadmap before relying on edge cases in production.
Result failure side
The failure type must belong to the Error family. Other failure types are not
supported yet.
Ok and Err role
Ok and Err support is and ensure checks. General value constructors are
still in development.
Final Go calls
A final Go call with several return values produces aTuple during return
inference. Split the values and check the error when you need a Result.
Generated error details
Error creation throughensure, type merging after or, and TypeScript _tag
output are still maturing. Treat generated payloads as evolving. See
Generate client types.
For limits around ensure x is Ok(), see
Ensure and narrowing.
Examples
See the error handling examples on GitHubRelated
Learn howensure checks a value and returns early when a condition fails.
Combining types
Define a closed set of named errors.
Ensure and narrowing
How
ensure connects checks to control flow.