aboutsummaryrefslogtreecommitdiff
path: root/doc/manual/rl-next/distinguish-throw-errors.md
blob: 243e33d61734c15f25dea2cf71db499179ac7ade (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
---
synopsis: "Distinguish between explicit throws and errors that happened while evaluating a throw"
cls: 1511
credits: Qyriad
category: Improvements
---

Previously, errors caused by an expression like `throw "invalid argument"` were treated like an error that happened simply while some builtin function was being called:

```
let
  throwMsg = p: throw "${p} isn't the right package";
in throwMsg "linuz"

error:
       … while calling the 'throw' builtin
         at «string»:2:17:
            1| let
            2|   throwMsg = p: throw "${p} isn't the right package";
             |                 ^
            3| in throwMsg "linuz"

       error: linuz isn't the right package
```

But the error didn't just happen "while" calling the `throw` builtin — it's a throw error!
Now it looks like this:

```
let
  throwMsg = p: throw "${p} isn't the right package";
in throwMsg "linuz"

error:
       … caused by explicit throw
         at «string»:2:17:
            1| let
            2|   throwMsg = p: throw "${p} isn't the right package";
             |                 ^
            3| in throwMsg "linuz"

       error: linuz isn't the right package
```

This also means that incorrect usage of `throw` or errors evaluating its arguments are easily distinguishable from explicit throws:

```
let
  throwMsg = p: throw "${p} isn't the right package";
in throwMsg { attrs = "error when coerced in string interpolation"; }

error:
       … while calling the 'throw' builtin
         at «string»:2:17:
            1| let
            2|   throwMsg = p: throw "${p} isn't the right package";
             |                 ^
            3| in throwMsg { attrs = "error when coerced in string interpolation"; }

       … while evaluating a path segment
         at «string»:2:24:
            1| let
            2|   throwMsg = p: throw "${p} isn't the right package";
             |                        ^
            3| in throwMsg { attrs = "error when coerced in string interpolation"; }

       error: cannot coerce a set to a string: { attrs = "error when coerced in string interpolation"; }
```

Here, instead of an actual thrown error, a type error happens first (trying to coerce an attribute set to a string), but that type error happened *while* calling `throw`.