Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Begin drafting try/catch proposal #2850

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft

Begin drafting try/catch proposal #2850

wants to merge 1 commit into from

Conversation

mirisuzanne
Copy link
Contributor

@mirisuzanne mirisuzanne commented Apr 28, 2020

Based on #2619

Rough syntax (with the unit-testing use-case):

@try {
  $test: my.function('bad arg');
} @catch $error {
  @include true.assert-equal(
    $error,
    "'bad arg' is not a valid argument for 'function'"
  );
}
  • resolve questions about what to catch, and how to shape it
  • more background & use-cases
  • finish the semantics

@chriseppstein
Copy link

Hey everyone, I've not been involved lately, but I hope you don't mind me swooping in and giving my thoughts on this proposal. I've always wanted to see @try statements in Sass, so I got excited by this.

The idea of catching a @warn is an interesting one, but also might be unexpected because @warn doesn't alter the control flow. I'd be interested to hear the use case(s) for this.

I have some questions about how @catch and @warn would interact:

  1. Because execution continues following @warn, what would be the behavior if several @warn statements are encountered while executing TryStatements? I can imagine several possibilities: a) the first @warn statement is passed to @catch; b) The last @warn statement is passed to @catch; c) All @warn statements are passed to @catch. d) the @catch is executed immediately when the @warn fires and may be executed several times as if it were the body of a loop. If c, would the value of message be a list in the case a warning.
  2. Given that execution continues for @warn, in the case of several nested @try ... @catch statements, does the @warn get passed to all of them or does it stop propagating unless "rewarned".

There's a use case around deciding that an error isn't the one you want to handle and rethrowing it. Given that an error message may have error specific values interpolated into the message that could be kind of tricky. What do you think about the idea of augmenting @error to have an identifier as well as a message? E.g. @error illegal-argument "Expected a string, got #{meta.inspect($arg1)}";. Then @catch could provide a discriminator so that only errors matching it are caught. E.g. @catch illegal-argument ($message) { ... }. Or the error object could have an extra key, etc.

When rethrowing an error, I think we'll want to preserve the original source location of the error. I think that might necessitate making a new data type.

If the main use case for using @catch with @warn is to silence a message do you think it makes sense to have a @try { ... } @silence ($warning) { ... } syntax where you can optionally inspect the warning and issue a new @warn if you want to print it out. In this case, should warn get a discriminator ident similar @error, seems like it would be handy for the same reasons.

  '}' '@catch' exceptionVar? '{'
  CatchStatements
  '}'
**exceptionVar** ::= '$' Identifier
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two nits:

  • Production names should be capitalized (ExceptionVar not exceptionVar).

  • Add a comment below explaining that no whitespace is allowed between '$' and Identifier. Or better yet, edit variables.md to have a PlainVariable that can be re-used without having to rewrite that caveat all over the place 😆.

Comment on lines +66 to +67
* Let `exception` be a map with the same identifier as `exceptionVar`,
a 'name' `throw`s at-rule
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm having a lot of trouble understanding this sentence.


This proposal defines a pair of new at-rule directives that must be used
together as a form of control. The `@try { ... } @catch { ... }` syntax captures
any thrown output (error or warning messages) from inside the `@try` block, and
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that catching warnings with this is unexpected. It's not how other programming languages work, and it may do very unexpected things with the control flow.

I'd like to punt on the question of how warnings are tested for now. It's much easier and safer to devise custom warning-capturing infrastructure, since you can just add strings to a list and you don't have to worry about globally coordinating return values.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants