-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Add better error messages for yaml selectors #2781
Conversation
b8ec47d
to
f66e573
Compare
There was a problem hiding this 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.
- name: union_plus | ||
definition: | ||
- union: | ||
- method: tag | ||
value: nightly | ||
- exclude: | ||
- method: tag | ||
value: hourly | ||
- method: tag | ||
value: foo |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 arbitrarykey: 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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
bbb9acc
to
2d63a4b
Compare
2d63a4b
to
46eadd5
Compare
There was a problem hiding this 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.
- name: union_plus | ||
definition: | ||
- union: | ||
- method: tag | ||
value: nightly | ||
- exclude: | ||
- method: tag | ||
value: hourly | ||
- method: tag | ||
value: foo |
There was a problem hiding this comment.
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()) |
There was a problem hiding this comment.
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:
keys = ",".join(definition.keys()) | |
keys = ", ".join(definition.keys()) |
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
CHANGELOG.md
and added information about my change to the "dbt next" section.