Error Handling
Effectful operations open connections, send requests, wait for messages, or send WebSocket frames. They return Result(_, error.GluegunError). Pure builders and accessors return plain values. Only response.body_text decodes the body (UTF-8). response.body always returns the raw bytes.
Pattern match on the variants that are important to your application. Keep a fallback for unexpected Erlang or decode errors.
import gleam/ioimport gleam/resultimport gluegun/clientimport gluegun/connectionimport gluegun/error
fn safe_get(conn) { use timeout <- result.try(connection.milliseconds(5000))
case client.get(conn, "/", [], timeout) { Ok(response) -> Ok(response) Error(error.Timeout) -> { io.println("request timed out") Error(error.Timeout) } Error(error.ConnectionDown(reason)) -> { io.println("connection down: " <> reason) Error(error.ConnectionDown(reason)) } Error(other) -> { io.println("request failed") Error(other) } }}Gluegun normalizes FFI errors at the API boundary. Erlang failures become GluegunError values. Raw Erlang terms do not leak.
HTTP collection cleanup
Section titled “HTTP collection cleanup”Once a high-level client helper gets a stream, it owns failure cleanup. On a collection error, it attempts to cancel the stream and drains queued messages for that stream, even if cancellation fails. It returns the original collection error. Cleanup failures produce a warning instead of replacing that error.
Cleanup preserves concurrent streams and connection-level messages. It does not close the shared connection or flush all of its messages. Gun processes cancellation asynchronously; messages in transit can arrive after the drain. The high-level helper does not return the failed stream handle. For strict mailbox isolation, use low-level stream ownership in a separate receiving process.
Error variants
Section titled “Error variants”| Variant | Meaning | Common cause |
|---|---|---|
Timeout |
An operation timed out. | The server was slow or not reachable, or the timeout was too short. |
ConnectionDown(String) |
The Gun connection went down. | The remote closed the connection, or the network failed. |
ConnectionError(String) |
Connection setup or use failed. | Incorrect host, port, transport, TLS, or Gun connection state. |
StreamError(String) |
A stream failure occurred. | A stream was canceled, reset, or rejected. |
InvalidOptions(String) |
Gluegun rejected the typed options. | A flow-control increment that is not positive, or an unsupported option shape. |
InvalidMessage(String) |
A protocol message did not agree with the API in use. | High-level client functions got an upgrade, push, or WebSocket message. Or the code received WebSocket frames before the upgrade was complete. |
UnsupportedFeature(String) |
The feature is not supported. | A WebSocket upgrade on an HTTP/2 connection (Gun does not support RFC 8441). Select Http1. |
ErlangError(String) |
An Erlang or FFI failure occurred that has no category. | An unexpected Gun or BEAM error crossed the FFI boundary. |
DecodeError(String) |
Decode failed. | An invalid FFI message shape, or a response body that is not UTF-8 given to response.body_text. |
See the error reference for the current error type definition.

