glerror
Error handling utilities with support for error kinds, context, and sources.
Types
Controls how much detail a Format function should produce.
pub type Detail {
High
Low
}
Constructors
-
HighThe expanded, hierarchical rendering (see
pretty_print). Context and sources are broken out onto their own lines, roughly:error: Not found context: 0: fetching user sources: ╰─▶ HTTP 404 -
LowThe compact, single-line rendering (see
to_string). Context and sources are folded into one line, roughly:Not found [fetching user] (source: HTTP 404)
A convenient error type for simple string-based errors.
This is the recommended type for most use cases where you don’t need to pattern match on specific error variants.
pub type Error =
KindError(String)
A lazy, detail-aware renderer for a value such as an error kind or source.
A Format is a function from FormatArgs to a String. It is kept lazy
so that the string is only built when the error is actually displayed, and
it receives the requested Detail level so the same value can render
compactly (Low) or with full hierarchy (High).
Construct one with string_format (a fixed string), inspect_format
(via string.inspect), or as_format (render another KindError, which
is how nested errors are embedded as sources). You can also write your own:
import glerror as error
let format: error.Format = fn(args) {
case args.detail {
error.High -> "a long, detailed message"
error.Low -> "short message"
}
}
pub type Format =
fn(FormatArgs) -> String
pub type Kind(kind) {
Kind(kind: kind, format: fn(FormatArgs) -> String)
}
Constructors
-
Kind(kind: kind, format: fn(FormatArgs) -> String)
KindError
opaqueA generic error type that supports error kinds, context layers, and source errors.
The kind parameter allows you to specify custom error variants for type-safe
error handling. Use Error (which is KindError(String)) for simple ad-hoc errors.
The source is stored as a lazy function to avoid unnecessary string construction when the error is not displayed.
pub opaque type KindError(kind)
Values
pub fn add_context(
err: KindError(kind),
context: String,
) -> KindError(kind)
Add a context layer to an error.
Context is added in a stack, with the most recent context appearing first when the error is displayed.
Example
import glerror as error
error.error("connection refused")
|> error.add_context("connecting to database")
|> error.add_context("initializing application")
pub fn as_format(
error: KindError(kind),
) -> fn(FormatArgs) -> String
pub fn context(
res: Result(value, KindError(kind)),
context: String,
) -> Result(value, KindError(kind))
Add context to a Result if it’s an error.
This is the primary way to add context when working with Result types. The Ok value passes through unchanged.
Example
parse_json(data)
|> glerror.context("parsing user data")
|> glerror.context("loading profile")
pub fn error(message: String) -> KindError(String)
Create a simple string-based error.
Example
import glerror as error
let err = error.error("File not found")
pub fn from_result(
res: Result(value, original_error),
kind: Kind(kind),
format_source: fn(original_error) -> fn(FormatArgs) -> String,
) -> Result(value, KindError(kind))
Convert a Result with a different error type to use KindError.
This is useful when integrating with libraries that use their own error types.
Example
int.parse("42")
|> error.from_result(
Kind("Invalid integer", fn(_) { "Invalid integer" }),
fn(_) { fn(_) { "Parse error" } }
)
pub fn inspect_format(term: anything) -> fn(FormatArgs) -> String
Formats a term using string.inspect.
pub fn kind(err: KindError(kind)) -> kind
Get the error kind from a KindError.
Example
import glerror as error
let err = error.new(error.to_kind(NotFound))
error.kind(err) // NotFound
pub fn lazy_context(
res: Result(value, KindError(kind)),
context: fn() -> String,
) -> Result(value, KindError(kind))
Add context to a Result using a lazy function.
The function is only called if the Result is an Error, avoiding unnecessary string construction in the success case.
Example
import glerror as error
fetch_user(user_id)
|> error.lazy_context(fn() {
"fetching user " <> int.to_string(user_id)
})
pub fn map_kind(
err: KindError(kind),
mapper: fn(kind) -> Kind(new_kind),
) -> KindError(new_kind)
Transform the error kind using a mapping function.
This is useful when converting between different error types.
Example
import glerror as error
pub type HttpError {
NotFound
ServerError
}
pub type AppError {
HttpFailed(HttpError)
ParseFailed
}
let http_err = error.new(error.to_kind(NotFound))
let app_err = error.map_kind(http_err, fn(e) { error.to_kind(HttpFailed(e)) })
pub fn new(kind: Kind(kind)) -> KindError(kind)
Create a new error from a custom error kind.
Example
import glerror as error
pub type MyError {
NotFound
InvalidInput
}
let err = error.new(error.to_kind(NotFound))
pub fn pretty_print(err: KindError(kind)) -> String
Format a KindError with hierarchical pretty printing.
This produces a tree-like output with numbered context sections and
box-drawing characters for sources, supporting nested errors via
as_format.
Example
import glerror as error
error.error("Not found")
|> error.add_context("fetching user")
|> error.add_context("loading dashboard")
|> error.with_source(fn(_) { "HTTP 404" })
|> error.pretty_print
Output:
error: Not found
context:
0: fetching user
1: loading dashboard
sources:
╰─▶ HTTP 404
pub fn string_format(s: String) -> fn(FormatArgs) -> String
pub fn to_string(err: KindError(kind)) -> String
Convert a KindError to a single-line string representation.
Example
import glerror as error
error.error("Database connection failed")
|> error.add_context("loading user")
|> error.add_context("fetching profile")
|> error.to_string
// "Database connection failed [loading user, fetching profile]"
pub fn with_source(
err: KindError(kind),
source: fn(FormatArgs) -> String,
) -> KindError(kind)
Attach a source error description.
This is useful when you want to include information about the underlying cause of the error without exposing the actual error type.
The source is stored as a lazy function and only evaluated when the error is displayed, avoiding unnecessary string construction.
Example
import glerror as error
error.error("Database query failed")
|> error.with_source(fn() { "Connection timeout after 30s" })
// With dynamic data
error.error("Database query failed")
|> error.with_source(fn() {
"Connection timeout at " <> format_timestamp(now())
})