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

  • High

    The 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
    
  • Low

    The 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

The arguments passed to a Format function when it is rendered.

Carries the requested detail level, which a Format inspects to decide how much to render.

pub type FormatArgs {
  FormatArgs(detail: Detail)
}

Constructors

pub type Kind(kind) {
  Kind(kind: kind, format: fn(FormatArgs) -> String)
}

Constructors

  • Kind(kind: kind, format: fn(FormatArgs) -> String)

A 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)

A convenient Result type alias for simple errors.

Use this when you want Result(value, Error) without repeating the error type.

pub type Result(value) =
  Result(value, KindError(String))

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 add_context_fn(
  err: KindError(kind),
  context: fn() -> String,
) -> KindError(kind)
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_kind(kind: kind) -> Kind(kind)
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())
})
Search Document