Skip to content

Commit 6e6c983

Browse files
committed
Begin drafting try/catch proposal
1 parent b7968bc commit 6e6c983

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed

proposal/try-catch.md

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# Support `@try` and `@catch` flow controls for error handling: Draft 1
2+
3+
*[(Issue)](https://github.com/sass/sass/issues/2619)*
4+
5+
## Table of Contents
6+
7+
## Background
8+
9+
> This section is non-normative.
10+
11+
In many situations, particularly when writing tests, it's useful to catch error
12+
and warning messages without breaking compilation. By adding `@try` and `@catch`
13+
at-rules similar to other control-flow syntax, authors will have more control
14+
over error handling, and the ability to test for error-cases.
15+
16+
Many large Sass projects currently use wrapper functions and mixins to catch and
17+
manage errors, with a parameter to toggle between throwing or returning the
18+
error message. But that relies on the special error handling to be built into
19+
every individual function or mixin that might error. By adding global controls,
20+
error-handling can happen either where the error is generated, or where it is
21+
defined.
22+
23+
## Summary
24+
25+
> This section is non-normative.
26+
27+
This proposal defines a pair of new at-rule directives that must be used
28+
together as a form of control. The `@try { ... } @catch { ... }` syntax captures
29+
any thrown output (error or warning messages) from inside the `@try` block, and
30+
allows the parser to continue compilation. The `@catch` block executes whenever
31+
an error or warning has been captured, allowing authors to determine how the
32+
error should be processed.
33+
34+
```scss
35+
@try {
36+
$test: my.function('bad arg');
37+
} @catch $error {
38+
@include true.assert-equal(
39+
$error,
40+
"'bad arg' is not a valid argument for 'function'"
41+
);
42+
}
43+
```
44+
45+
## Syntax
46+
47+
<x><pre>
48+
**TryCatchRule** ::= '@try' '{'
49+
&#32; TryStatements
50+
&#32; '}' '@catch' exceptionVar? '{'
51+
&#32; CatchStatements
52+
&#32; '}'
53+
**exceptionVar** ::= '$' Identifier
54+
</pre></x>
55+
56+
## Semantics
57+
58+
To execute a `TryCatchRule` `rule`:
59+
60+
* Let `exceptions`
61+
62+
* Execute the contents `try` of `rule`'s `TryStatements`
63+
64+
* If an `@error` or `@warn` rule `throw` is encountered:
65+
66+
* Let `exception` be a map with the same identifier as `exceptionVar`,
67+
a 'name' `throw`s at-rule
68+
69+
> Currently either `@error` or `@warn`
70+
71+
* Let `message` be the value of the `throw`'s `expression`
72+
73+
* If `name` is `@error`, ignore any remaining statements in `try`
74+
75+
* Otherwise complete compilation of the `TryStatements`
76+
77+
* If `exceptionVar` is defined
78+
79+
* Let `exception` be a map variable with the same name as `exceptionVar`'s
80+
identifier.
81+
82+
* Let `exception` have a key 'name' with the value of `name`
83+
84+
* Let `exception` have a key 'messsage' with the value of `message`
85+
86+
> assign `message` to identifier `catchMessage`...
87+
88+
> Execute the contents of `rule`'s `CatchStatements` with `catchMessage` and
89+
> `catchType`...
90+
91+
* Otherwise, ignore the remainder of the `TryCatchRule`
92+

0 commit comments

Comments
 (0)