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

Implement ability to skip over list items if their field resolution raises an error #6

Open
wants to merge 4 commits into
base: dev
Choose a base branch
from

Conversation

amomchilov
Copy link

@amomchilov amomchilov commented May 31, 2023

What

A working proposal for implementing rmosolgo#4496

This PR adds new skip_nodes_on_raise and on_raise arguments to the field API which lets you declare that a List's items can be skipped on error:

field :array_of_nullable_skippable_items,
[ItemType, null: true],
method: :items_list,
null: false,
skip_nodes_on_raise: true,
on_raise: ->(err, current_object, args, context, current_field, nearest_skippable_list_item) {
puts(:array_of_required_skippable_items)
context.skip_from_parent_list
}

Other

Two of the test suites fail, not sure why, the failures don't seem related to my changes.

I made the target dev branch just as a placeholder for this PR.

@amomchilov amomchilov force-pushed the Alex/item_skipping/per-field-callback-API branch 3 times, most recently from 6015655 to 8b0a52d Compare May 31, 2023 22:39
@amomchilov amomchilov force-pushed the Alex/item_skipping/per-field-callback-API branch 4 times, most recently from 0abb3b0 to d50e635 Compare June 1, 2023 13:45
@amomchilov amomchilov marked this pull request as ready for review June 1, 2023 13:59
@amomchilov amomchilov self-assigned this Jun 1, 2023
end

selection_result.graphql_skip_at(result_name)
else # Propograte up to find the first list this item can be skipped from.
Copy link

Choose a reason for hiding this comment

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

Typo in Propograte

@@ -566,6 +609,19 @@ def set_result(selection_result, result_name, value)
set_result(parent, name_in_parent, nil)
set_graphql_dead(selection_result)
end
elsif value == GraphQL::Execution::SKIP_FROM_PARENT_LIST

Choose a reason for hiding this comment

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

Where is value set to GraphQL::Execution::SKIP_FROM_PARENT_LIST?

Choose a reason for hiding this comment

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

Oh, I see in your example the callback sets it. I was expecting the library to do this automatically since the user has already opted into this functionality. In any case it's not super clear the callback is supposed to do this.

Copy link
Author

@amomchilov amomchilov Jun 1, 2023

Choose a reason for hiding this comment

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

Yeah you're right, perhaps it should be the default in the case of skip_nodes_on_raise: true, on_raise: nil?

Choose a reason for hiding this comment

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

Yeah, I think it should be the default. It might be good to make it the behavior even if on_raise is set. In the callback we can perform some logging and let the section be skipped by default. Only in rare cases would we override the skip behavior in the callback.

if nearest_skippable_parent_result && (on_raise_callback = nearest_skippable_parent_result.field.on_raise_callback)
begin
nearest_skippable_list_item = nearest_skippable_parent_result.represented_value.object
on_raise_callback.call(err, object, kwarg_arguments, context, nearest_skippable_parent_result.field, nearest_skippable_list_item)

Choose a reason for hiding this comment

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

Is the callback expected to return anything?

Copy link
Author

@amomchilov amomchilov Jun 1, 2023

Choose a reason for hiding this comment

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

Yep! It has the same behaviour as rescue_from (which is what ends up being called by query.handle_or_reraise(err) a few lines below).

I list the possibilities in the "Extend the existing schema-level rescue_from callback" section of the parent issue.

In addition to those preexisting options, you now also have the choice to return context.skip_from_parent_list which will trigger the new skipping behaviour.

Choose a reason for hiding this comment

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

Ah, I should have read the "supplementary materials" more closely :)

# @param fallback_value [Object] A fallback value if the method is not defined
# @param skip_nodes_on_raise [Boolean] true if this field's list items should be skipped, if resolving them led to an error being raised. Only applicable to List types.
# @param on_raise [Proc] A callback that's invoked when an error is raised while resolving this field's list items. Only applicable to List types.
def initialize(type: nil, name: nil, owner: nil, null: nil, description: :not_given, deprecation_reason: nil, method: nil, hash_key: nil, dig: nil, resolver_method: nil, connection: nil, max_page_size: :not_given, default_page_size: :not_given, scope: nil, introspection: false, camelize: true, trace: nil, complexity: nil, ast_node: nil, extras: EMPTY_ARRAY, extensions: EMPTY_ARRAY, connection_extension: self.class.connection_extension, resolver_class: nil, subscription_scope: nil, relay_node_field: false, relay_nodes_field: false, method_conflict_warning: true, broadcastable: nil, arguments: EMPTY_HASH, directives: EMPTY_HASH, validates: EMPTY_ARRAY, fallback_value: :not_given, skip_nodes_on_raise: false, on_raise: nil, &definition_block)

Choose a reason for hiding this comment

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

Nit: can we put each param on its own line for readability and cleaner diffs?

Copy link
Author

Choose a reason for hiding this comment

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

Not a nit, the git conflicts on this line are pretty painful 😅

cc @rmosolgo

@amomchilov amomchilov force-pushed the Alex/item_skipping/per-field-callback-API branch from 6bb41e8 to f25db79 Compare June 16, 2023 15:44
@tgwizard tgwizard removed their request for review November 7, 2023 12:59
@tgturner-shopify tgturner-shopify removed their request for review March 7, 2024 14:50
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.

3 participants