You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/content/docs/guide/error-handling.md
+82-36Lines changed: 82 additions & 36 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,9 +1,9 @@
1
1
---
2
2
title: Error Handling
3
-
description: Result, Option, effect fn auto-propagation, guard, and deriving From for error conversion.
3
+
description: Result, Option, unwrap operators (!, ??, ?), effect fn, and guard for safe error handling.
4
4
---
5
5
6
-
Almide has no exceptions. All errors are values, represented by `Result[T, E]` and `Option[T]`. The `effect fn` system automates error propagation, making error handling both safe and concise.
6
+
Almide has no exceptions. All errors are values, represented by `Result[T, E]` and `Option[T]`. Three postfix operators -- `!`, `??`, and `?` -- provide concise, explicit control over unwrapping.
7
7
8
8
## Result
9
9
@@ -50,21 +50,90 @@ let upper = option.map(map.get(config, "name"), (s) => string.to_upper(s))
50
50
let result = option.to_result(map.get(config, "name"), "name is required")
51
51
```
52
52
53
-
## effect fn and auto-propagation
53
+
## Unwrap operators: `!`, `??`, `?`
54
54
55
-
The key to ergonomic error handling in Almide is `effect fn`. Inside an `effect fn`, expressions returning `Result[T, E]` are automatically unwrapped:
55
+
Almide provides three postfix operators for unwrapping `Result` and `Option` values. These are the primary way to work with fallible values.
56
+
57
+
### `!` — propagate error
58
+
59
+
`expr!` unwraps a `Result` or `Option`. If the value is `err(e)` or `none`, the enclosing `effect fn` immediately returns the error. Only valid inside `effect fn`.
let user = list.first(users)! // none becomes err, propagated
74
+
ok(user.name)
75
+
}
76
+
```
77
+
78
+
### `??` — fallback value
79
+
80
+
`expr ?? fallback` unwraps with a default. If the value is `err(_)` or `none`, the fallback is used instead. Valid anywhere (not limited to `effect fn`).
81
+
82
+
```almide
83
+
let port = int.parse(port_str) ?? 8080
84
+
let name = map.get(env, "USER") ?? "anonymous"
85
+
```
86
+
87
+
### `?` — convert to Option
88
+
89
+
`expr?` converts a `Result[T, E]` to `Option[T]`, discarding the error. On `Option`, it is a passthrough. Valid anywhere.
90
+
91
+
```almide
92
+
let parsed = int.parse(input)? // Result[Int, String] -> Option[Int]
93
+
let found = map.get(config, "key")? // Option[String] -> Option[String] (passthrough)
For applications with multiple error sources, define a variant error type with `deriving From`:
100
-
101
-
```almide
102
-
type AppError =
103
-
| Io(IoError)
104
-
| Parse(ParseError)
105
-
deriving From
106
-
```
107
-
108
-
`deriving From` generates automatic conversions from each inner error type to the variant. This enables seamless error propagation across different error types:
Types can derive built-in conventions using `:` after the type name:
322
322
323
323
```almide
324
-
type AppError: From =
325
-
| Io(IoError)
326
-
| Parse(ParseError)
327
-
328
324
type Color: Eq =
329
325
| Red
330
326
| Green
331
327
| Blue
332
328
```
333
329
334
-
This generates implementations automatically. Available conventions: `Eq`, `Repr`, `Ord`, `Hash`, `Codec`, `From`. See[Error Handling](/docs/guide/error-handling/) and[Protocols](/docs/guide/protocols/) for details.
330
+
This generates implementations automatically. Available conventions: `Eq`, `Repr`, `Ord`, `Hash`, `Codec`. See [Protocols](/docs/guide/protocols/) for details.
0 commit comments