8000 Document mixin flow issues when using `error` mixin · Issue #174 · oddbird/true · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Document mixin flow issues when using error mixin #174

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

Closed
oscarmarcelo opened this issue Sep 6, 2020 · 7 comments · Fixed by #178
Closed

Document mixin flow issues when using error mixin #174

oscarmarcelo opened this issue Sep 6, 2020 · 7 comments · Fixed by #178

Comments

@oscarmarcelo
Copy link
oscarmarcelo commented Sep 6, 2020

I found a kind of edge case, and honestly I don't think that there may be a viable solution without Sass implementing try/catch or something similar, but I'm pointing this anyway in case someone finds a solution, since I didn't find anything yet.

Consider the following:

@use "sass:meta"

=width ($length)
  @if meta.type-of($length) == map
    @error "Maps aren't allowed"

  width: $length


+width((a: 1px))

Now if we replace @error by True's +throw.error:

  1. +throw.error now @returns something to the mixin, allowing it to continue its flow, instead of stopping it.
  2. The compilation breaks because Sass doesn't allow maps in CSS output (Error: <insert-map-here> isn't a valid CSS value.).

Now lets explore a bit further:

@use "sass:meta"
@use "sass-true" as *

@function not-color ($value)
  @if meta.type-of($value) == color
    @return error("Not color", null, true)
  @return $value    

=width ($length)
  @if $length == red
    +error("Not red", null, true)
  width: not-color($length)
  min-width: 1px


+describe("Errors")
  +it("Shouldn't accept colors")
    +output
      +width(red)
    +expect
      /* ERROR: */
      /*   Not red */

And the result is:

/* Test: Errors */
/*   ASSERT: Shouldn't accept colors   */
/*   OUTPUT   */
.test-output {
  /* ERROR: */
  /*   Not red */
  width: "ERROR: Not color";
  min-width: 1px;
}

/*   END_OUTPUT   */
/*   EXPECTED   */
.test-output {
  /* ERROR: */
  /*   Not red */
}

The flow should stop on the first error, but instead it continues the mixin flow, outputting additional content and errors.

Is there something that can be currently done about this?

@oscarmarcelo oscarmarcelo changed the title Avoiding native Sass errors when using error mixin Stopping mixin flow when using error mixin Sep 6, 2020
@mirisuzanne
Copy link
Member

Hmmm, I think if we force error returns to be strings before output, that might do it? '#{$output}'

@mirisuzanne
Copy link
Member

But you're right, we can't stop compilation, because that defeats the purpose.

@oscarmarcelo
Copy link
Author

Hmmm, I think if we force error returns to be strings before output, that might do it? '#{$output}'

I'm confused. Can you give an example, please?

@mirisuzanne
Copy link
Member

@oscarmarcelo I'm sorry, I totally misread the issue and solved the wrong problem.

I don't see any way to make Sass stop compilation of a single mixin or function, without stopping the entire compilation process - which is what you get from a built-in @error call. So I don't think there is any fix that True can implement for this.

But you do have the tools to implement it on your end if necessary. The only solution I know of would be to put the rest of the mixin behind an @else condition:

=width ($length)
  @if $length == red
    +error("Not red", null, true)
  @else 
    width: not-color($length)
    min-width: 1px

That way you either get the error or the output, but never both.

@mirisuzanne mirisuzanne changed the title Stopping mixin flow when using error mixin Document mixin flow issues when using error mixin Sep 25, 2020
@oscarmarcelo
Copy link
Author
oscarmarcelo commented Oct 17, 2020

I'm sorry for opening this again, but I think I have viable solution to this issue.

I'm still trying to understand how +contains work, but what if we check if @content starts with something (in this case, the error message)?

In the method I used in the example above (using input validation to interrupt the mixin flow instead of controlling with @if statements) the only thing that matters to the assertion is the first error that is output, even if there are more errors or CSS output after it.

I suggest adding a +starts-with for this, or, if you prefer, a $starts-with (bool) argument in +contains.

Example

Using the code in the first message of this issue, the following test would pass:

+describe("Errors")
  +it("Shouldn't accept colors")
    +output
      +width(red)
    +starts-with
      /* ERROR: */
      /*   Not red */

@mirisuzanne
Copy link
Member

The contains mixin compiles exactly the same as expect, but with a different wrapping comment to signal what the JS integration should compare between the blocks. You can use that to see if there is an error in the output (regardless of position). I'm not sure why the starts-with logic would matter here, as you can check for a specific error in the output. We could add starts- or ends-with, but it doesn't seem all that useful to me.

in any case - we can't check those values inside @content, or change compilation from our end based on errors encountered. All of the output/expect/contains comparisons are handled after compilation completes. So this:

  1. Is a solution for checking the presence of one specific error
  2. Is not a solution to keep errors from cascading
+describe("Errors")
  +it("Shouldn't accept colors")
    +output
      +width(red)
    +contains
      /* ERROR: */
      /*   Not red */

@oscarmarcelo
Copy link
Author

Yes, you are totally right!
I got so carried away with the idea that I forgot about Sass native errors. 😅

I guess I really have to abandon the method of using input validation to decide wether the mixin should continue its flow or not...

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

Successfully merging a pull request may close this issue.

2 participants
0