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

Add better error messages for yaml selectors #2781

Merged

Conversation

gshank
Copy link
Contributor

@gshank gshank commented Sep 21, 2020

resolves #2700

Description

Changed hologram to provide more information in the exceptions, and modified selector error messages to include yaml output and more information.

Checklist

  • I have signed the CLA
  • I have run this code in development and it appears to resolve the stated issue
  • This PR includes tests, or tests are not required/relevant for this PR
  • I have updated the CHANGELOG.md and added information about my change to the "dbt next" section.

@cla-bot cla-bot bot added the cla:yes label Sep 21, 2020
gshank added a commit that referenced this pull request Sep 21, 2020
@gshank gshank force-pushed the feature/2700-improve-yaml-selector-errors branch from b8ec47d to f66e573 Compare September 23, 2020 15:15
Copy link
Contributor

@jtcohen6 jtcohen6 left a comment

Choose a reason for hiding this comment

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

Nice work on these exceptions! I noted one more case that I think we should try to catch + raise.

I think I understand the connection to dbt-labs/hologram#35, insofar as when I took this PR for a spin and defined bad selectors I was more likely to get an eager, generic error rather than a more precise, descriptive one.

Comment on lines +44 to +53
- name: union_plus
definition:
- union:
- method: tag
value: nightly
- exclude:
- method: tag
value: hourly
- method: tag
value: foo
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you also add an exception + test for quite similar case, which I've seen a few folks run into:

selectors:
  - name: mixed_syntaxes
    definition:
      key: value
      method: tag
      value: foo
      union:
        - method: tag
          value: nightly
        - exclude:
          - method: tag
            value: hourly

The issue here is that contradictory dict arguments are being passed to definition, and it's not at all clear which ones it's using.

Copy link
Contributor Author

@gshank gshank Sep 23, 2020

Choose a reason for hiding this comment

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

Are we talking about the "key: value" piece? or having a union in a dictionary without a 'union' above it? I was under the impression that the above should be:

selectors:
    - name: mixed_syntaxes
      definition:
         union:
           - method: tag
              value: foo
            - method: tag
               value: nightly
            - exclude:
                 method: tag
                 value: hourly

So having a 'union' in a single dictionary should be an error, and having an invalid keyword 'key' should be an error?

Copy link
Contributor

@jtcohen6 jtcohen6 Sep 23, 2020

Choose a reason for hiding this comment

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

Right on—the way you've defined it is how it should be. I've seen users write the version I put above, which neither throws an error nor works the way they'd expect. I think we should check to see that definition is one of:

  • string
  • dict w/ 1 argument (union, intersection, or arbitrary key: value)
  • dict w/ 2 arguments (must be method + value)

and throw an exception if it doesn't meet one of those three criteria. Does that sound reasonable?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think there are quite a few other arguments that you can put in a dict, such as 'children', 'parents', etc. What I did and pushed was to check that if there is a union or intersection operator in the root level, there's not also a 'method' key. The way the code worked was that it would just. ignore additional dict keys if there was a union or intersection, so that takes the "way it works" and creates an error.

Let me know if you see any other situations that are problematic.

Copy link
Contributor

@jtcohen6 jtcohen6 Sep 23, 2020

Choose a reason for hiding this comment

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

Ah, that's a really good point about children, parents, child_depth, etc. Silly of me to forget, sorry.

That sounds about right to me. Would it be possible to generalize this:

check that if there is a union or intersection operator in the root level, there's not also a 'method' key.

To be: "if there is a union or intersection operator in the root level, there should be no other dict arguments."

OR: "There should be only one dict argument, unless method is one of the arguments."

I think this would also avoid the weirdness of something like:

selectors:
    - name: multiple_sets
      definition:
         intersection:
           - method: tag
             value: foo
           - method: tag
             value: bar
         union:
           - method: tag
             value: nightly
           - exclude:
              - method: tag
                value: hourly

If I understand correctly, the current behavior would be to take the first set and ignore the second set entirely. Really we should throw an error.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, that would cover more situations. Will change.

Copy link
Contributor

Choose a reason for hiding this comment

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

It looks like this now raises a much better error message:

selectors:
    - name: intersection_and_method
      definition:
         intersection:
           - method: tag
             value: foo
           - method: tag
             value: bar
         method: tag
         value: bar
 You cannot have both method and intersection keys in a root level selector definition:

Nice!

The multiple_sets definition above, however, still doesn't raise an error.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Strange. For the multiple_set example I get: Only a single 'union' or 'intersection' key is allowed in a root level selector definition; found intersection,union.

Copy link
Contributor

Choose a reason for hiding this comment

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

This now works wonderfully!

Could not read selector file data: Runtime Error
    Only a single 'union' or 'intersection' key is allowed in a root level selector definition; found intersection,method,value.

I'm sure this was on me for not pulling the latest remote changes.

@gshank gshank force-pushed the feature/2700-improve-yaml-selector-errors branch 2 times, most recently from bbb9acc to 2d63a4b Compare September 23, 2020 20:20
@gshank gshank force-pushed the feature/2700-improve-yaml-selector-errors branch from 2d63a4b to 46eadd5 Compare September 25, 2020 18:53
@gshank gshank requested review from kwigley and removed request for beckjake September 28, 2020 14:02
Copy link
Contributor

@jtcohen6 jtcohen6 left a comment

Choose a reason for hiding this comment

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

Thanks for this! I know that we'll continue to make iterative improvements on YAML selectors. I think this is a big step toward avoiding unnecessary surprises.

Comment on lines +44 to +53
- name: union_plus
definition:
- union:
- method: tag
value: nightly
- exclude:
- method: tag
value: hourly
- method: tag
value: foo
Copy link
Contributor

Choose a reason for hiding this comment

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

This now works wonderfully!

Could not read selector file data: Runtime Error
    Only a single 'union' or 'intersection' key is allowed in a root level selector definition; found intersection,method,value.

I'm sure this was on me for not pulling the latest remote changes.

if (isinstance(definition, dict) and
('union' in definition or 'intersection' in definition) and
rootlevel and len(definition) > 1):
keys = ",".join(definition.keys())
Copy link
Contributor

Choose a reason for hiding this comment

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

Incredibly nit-picky and totally up to you:

Suggested change
keys = ",".join(definition.keys())
keys = ", ".join(definition.keys())

@gshank gshank merged commit dbca540 into dev/kiyoshi-kuromiya Sep 29, 2020
@kwigley kwigley deleted the feature/2700-improve-yaml-selector-errors branch February 5, 2021 17:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Better error messaging for YAML selectors
3 participants