snag
Types
A concise alias for a Result that uses a Snag as the error value.
pub type Result(t) =
Result(t, Snag)
A Snag is a boilerplate-free error type that can be used to track why an error happened, though does not store as much detail on specific errors as a custom error type would.
It is useful in code where it must either pass or fail, and when it fails we want good debugging information to print to the user. i.e. Command line tools, data processing pipelines, etc.
If it not suited to code where the application needs to make a decision about what to do in the event of an error, such as whether to give up or to try again. i.e. Libraries, web application backends, API clients, etc. In these situations it is recommended to create a custom type for your errors as it can be pattern matched on and have any additional detail added as fields.
pub type Snag {
Snag(issue: String, cause: List(String))
}
Constructors
-
Snag(issue: String, cause: List(String))
Values
pub fn context(
result: Result(success, Snag),
issue: String,
) -> Result(success, Snag)
Add additional contextual information to a Snag wrapped in a Result.
Example
error("Not enough credit")
|> context("Unable to make purchase")
|> result.map_error(line_print)
// -> Error("error: Unable to make purchase <- Not enough credit")
pub fn error(issue: String) -> Result(success, Snag)
Create a new Snag wrapped in a Result with the given issue text.
Example
error("Not enough credit")
// -> Error(new("Not enough credit"))
pub fn layer(snag: Snag, issue: String) -> Snag
Add additional contextual information to a Snag.
See also the context function for adding contextual information to a Snag
wrapped in a Result.
Example
new("Not enough credit")
|> layer("Unable to make purchase")
|> line_print
// -> "error: Unable to make purchase <- Not enough credit"
pub fn line_print(snag: Snag) -> String
Turn a snag into a single-line string, optimised for compactness. This may be useful for logging snags.
Example
new("Not enough credit")
|> layer("Unable to make purchase")
|> layer("Character creation failed")
|> line_print
// -> "error: Character creation failed <- Unable to make purchase <- Not enough credit"
pub fn map_error(
result: Result(a, b),
with describer: fn(b) -> String,
) -> Result(a, Snag)
Map the error type in a Result to a Snag with the given describing
function.
The describing function should produce a human friendly text reprensentation of the error.
Example
my_app.read_file("api_key.txt")
|> snag.map_error(my_app.describe_error)
|> snag.context("Could not load API key")
|> snag.line_print
// -> "error: Could not load API key <- File is locked"
pub fn new(issue: String) -> Snag
Create a new Snag with the given issue text.
See also the error function for creating a Snag wrapped in a Result.
Example
new("Not enough credit")
|> line_print
// -> "error: Not enough credit"
pub fn pretty_print(snag: Snag) -> String
Turn a snag into a multi-line string, optimised for readability.
Example
new("Not enough credit")
|> layer("Unable to make purchase")
|> layer("Character creation failed")
|> pretty_print
// -> "error: Character creation failed
//
// cause:
// 0: Unable to make purchase
// 1: Not enough credit
// "
pub fn replace_error(
result: Result(a, b),
with issue: String,
) -> Result(a, Snag)
Replace the error type in a Result with a Snag with the given
issue text.
This is especially useful for converting functions that return a Nil
error into a Snag. Always prefer using the map_error function for
non Nil errors when possible.
Example
dict.get(users, "user_id")
|> snag.replace_error("User not found in dict")
|> snag.context("Could not get user data")
|> snag.line_print
// -> "error: Could not get user data <- User not found in dict"