Improve docs on try/exceptions
This commit is contained in:
parent
b8c70f9550
commit
a449ea1085
@ -22,6 +22,17 @@
|
|||||||
color: var(--c-text-2);
|
color: var(--c-text-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.markdown h3 {
|
||||||
|
font-size: 1.35rem;
|
||||||
|
line-height: 1.75rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
margin-top: 1.75rem;
|
||||||
|
font-family: Inter, sans-serif;
|
||||||
|
opacity: 0.9;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--c-text-2);
|
||||||
|
}
|
||||||
|
|
||||||
.markdown ul {
|
.markdown ul {
|
||||||
list-style-type: disc;
|
list-style-type: disc;
|
||||||
list-style-position: inside;
|
list-style-position: inside;
|
||||||
|
@ -1,49 +1,150 @@
|
|||||||
---
|
---
|
||||||
layout: ../../../layouts/PagesLayout.astro
|
layout: ../../../layouts/PagesLayout.astro
|
||||||
title: Try expressions
|
title: Try/Exceptions
|
||||||
---
|
---
|
||||||
|
|
||||||
# Try expressions
|
# Try/exceptions
|
||||||
|
|
||||||
|
Unlike PHP, in THP all errors must be explicitly declared
|
||||||
|
and handled.
|
||||||
|
|
||||||
|
## Declare that a function returns an exception
|
||||||
|
|
||||||
|
To declare a possible error return value the `Result` enum
|
||||||
|
is used.
|
||||||
|
|
||||||
|
For example, a function that returned a `DivisionByZero`
|
||||||
|
may be written like this:
|
||||||
|
|
||||||
```thp
|
```thp
|
||||||
fun get_value() -> Result[Int, String] { ... }
|
fun invert(Int number) -> Result[Int, DivisonByZero]
|
||||||
|
|
||||||
|
|
||||||
// treating errors as normal enums
|
|
||||||
val result = match get_value()
|
|
||||||
case Ok(result) { result }
|
|
||||||
case Err(error) { return error }
|
|
||||||
|
|
||||||
|
|
||||||
// get the value if Ok, otherwise re-throw
|
|
||||||
val result = try get_value()
|
|
||||||
|
|
||||||
// get the value if Ok, return a new value otherwise
|
|
||||||
val result = try get_value() return Err("new error")
|
|
||||||
|
|
||||||
// get the value if Ok, assign a new value otherwise
|
|
||||||
Int result = try get_value() else 20
|
|
||||||
|
|
||||||
// get the value if Ok, otherwise run block with the error value
|
|
||||||
val result = try get_value()
|
|
||||||
with error
|
|
||||||
{
|
{
|
||||||
// handle error
|
if number == 0
|
||||||
|
{
|
||||||
|
return Err(DivisionByZero())
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(1 / number)
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
In the previous segment, `Result[Int, DivisionByZero]` denotates
|
||||||
|
that the function may return either an `Int` or an `DivisionByZero`.
|
||||||
|
|
||||||
|
To return the error we use `Err(...)`, and to return the succes value
|
||||||
|
we use `Ok(...)`.
|
||||||
|
|
||||||
|
The error may be of any datatype.
|
||||||
|
|
||||||
|
|
||||||
fun throws_exception() -> Result[Int, MyException|MyOtherException] { ... }
|
### Multiple error returns
|
||||||
|
|
||||||
val result = try throws_exception() catch
|
If there are multiple error types that the function can return,
|
||||||
case MyException(e)
|
you can use the `|` operator:
|
||||||
{
|
|
||||||
// deal with MyException
|
|
||||||
}
|
|
||||||
case MyOtherException(e)
|
|
||||||
{
|
|
||||||
// deal with MyOtherException
|
|
||||||
}
|
|
||||||
|
|
||||||
|
```thp
|
||||||
|
fun sample() -> Result[Int, Exception1|Exception2|Exception3]
|
||||||
|
{ /* ... */}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Handle an error
|
||||||
|
|
||||||
|
Since `Result` is an enum we can use pattern matching to
|
||||||
|
get the ok value, or handle the error:
|
||||||
|
|
||||||
|
```thp
|
||||||
|
val result = match inverse(5)
|
||||||
|
case ::Ok(value) { value }
|
||||||
|
case ::Err(error) { return error }
|
||||||
|
```
|
||||||
|
|
||||||
|
However, THP provides syntactic sugar for many common
|
||||||
|
patterns for error handling.
|
||||||
|
|
||||||
|
## Try expressions
|
||||||
|
|
||||||
|
There are several try expressions that simplify error handling:
|
||||||
|
|
||||||
|
### Naked try
|
||||||
|
|
||||||
|
Using a `try` followed by an expression will execute the
|
||||||
|
expression, and if `Ok` is returned, it will return it's value.
|
||||||
|
If `Err` is returned, the error will be re-thrown.
|
||||||
|
|
||||||
|
```thp
|
||||||
|
fun sample(Int x) -> Result[Int, DivisionByZero]
|
||||||
|
{
|
||||||
|
val result = try inverse(x)
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If `inverse(x)` fails, the error will be returned again.
|
||||||
|
|
||||||
|
If `inverse(x)` succeedes, its value will be assigned to `result`.
|
||||||
|
|
||||||
|
|
||||||
|
### Try/return
|
||||||
|
|
||||||
|
Try/return will run a function and assign its value if `Ok` is found.
|
||||||
|
Otherwise, it will return a new value specified by the programmer.
|
||||||
|
|
||||||
|
```thp
|
||||||
|
fun sample(Int x) -> String
|
||||||
|
{
|
||||||
|
val result = try inverse(x) return "0 was found"
|
||||||
|
|
||||||
|
if result == 2 { "2 was found" }
|
||||||
|
else { "other number was found" }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If `inverse(x)` fails, `"0 was found"` will be returned.
|
||||||
|
|
||||||
|
If `inverse(x)` succeedes, its value will be assigned to `result`
|
||||||
|
and the code will continue to execute normally.
|
||||||
|
|
||||||
|
|
||||||
|
### Try/else
|
||||||
|
|
||||||
|
Try/else will run an expression and assign its value if `Ok`.
|
||||||
|
Otherwise it will assign a second value.
|
||||||
|
|
||||||
|
```thp
|
||||||
|
fun sample(Int x) -> Int
|
||||||
|
{
|
||||||
|
val result = try inverse(x) else 0.0
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If `inverse(x)` fails, `0.0` will be assigned to `result`.
|
||||||
|
|
||||||
|
If `inverse(x)` succeedes, its value will be assigned to `result`.
|
||||||
|
|
||||||
|
|
||||||
|
### Try/catch
|
||||||
|
|
||||||
|
Try/catch will run an expression and assign its value if `Ok`.
|
||||||
|
Otherwise it will run a block of code, which will handle
|
||||||
|
the error and assign a value as well.
|
||||||
|
|
||||||
|
```thp
|
||||||
|
fun sample(Int x)
|
||||||
|
{
|
||||||
|
val result = try inverse(x)
|
||||||
|
catch DivisionByZero e
|
||||||
|
{
|
||||||
|
// Handle `e`
|
||||||
|
// ...
|
||||||
|
|
||||||
|
0.0
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user