Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

try-catch

The try-catch expression allows you to handle errors gracefully by providing a fallback value when an expression fails.

Syntax

try <expr> catch <expr>
try <expr> catch(<binder>) <expr>

Behavior

  • If the try expression succeeds, its result is returned
  • If the try expression fails (produces an error), the catch expression is evaluated instead
  • The catch expression receives the same input as the try expression
  • With catch(<binder>), <binder> is bound to a dict describing the failure ({"message": <string>, "value": <any>}) for the duration of the catch expression
  • break/continue inside the try expression are not treated as errors; they propagate to the enclosing loop instead of triggering catch

Examples

Basic Error Handling

# When the expression succeeds
try: "value" catch: "unknown"
# => "value"

# When the expression fails
try: get("missing") catch: "default"
# => "default"

Chaining with Pipe

# Try to parse as JSON, fallback to the raw string
import "json"
| "not json"
| try: json::json_parse() catch: self
# => "not json"

# Complex fallback logic
import "json"
| {"data": "[1, 2]"}
| try: do get("data") | json::json_parse(); catch: []
# => [1, 2]

Nested Try-Catch

# Multiple fallback levels
try: get("primary") catch: try: get("secondary") catch: "default"
# => "default"

Error Binder

# Bind the failure to `e` and inspect its message
try: error("boom") catch(e): e["message"]
# => "boom"

Raising Any Value

error accepts a value of any type. e["value"] returns it unchanged, while e["message"] holds its string form. For errors that were not raised with error, and for error called with a string, e["value"] is the message.

try: error({"code": 404, "path": "/a"}) catch(e): e["value"]["code"]
# => 404

Error Suppression (?)

The error suppression operator ? provides a concise way to handle errors by returning None when an expression fails, instead of raising an error. This is equivalent to using a regular try-catch with a default fallback.

Examples

# Equivalent to a regular try-catch with a default value
get("missing")? | is_none
# => true

In this example, if get("missing") fails, the result will be None rather than an error.