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

Set default timeout for GraphQL schema validation #5258

Merged
merged 2 commits into from
Mar 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion guides/queries/timeout.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,21 @@ end

Queries can originate from a user, and may be crafted in a manner to take a long time to validate against the schema.

It is possible to limit how many seconds the static validation rules and analysers are allowed to run before returning a validation timeout error. The default is no timeout.
It is possible to limit how many seconds the static validation rules and analysers are allowed to run before returning a validation timeout error. By default, validation and query analysis have a 3-second timeout. You can customize this timeout or disable it completely:

For example:

```ruby
# Customize timeout (in seconds)
class MySchema < GraphQL::Schema
# Applies to static validation and query analysis
validate_timeout 10
end

# OR disable timeout completely
class MySchema < GraphQL::Schema
validate_timeout nil
end
```

**Note:** This configuration uses Ruby's built-in `Timeout` API, which can interrupt IO calls mid-flight, resulting in [very weird bugs](https://www.mikeperham.com/2015/05/08/timeout-rubys-most-dangerous-api/). None of GraphQL-Ruby's validators make IO calls but if you want to use this configuration and you have custom static validators that make IO calls, open an issue to discuss implementing this in an IO-safe way.
2 changes: 1 addition & 1 deletion lib/graphql/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -827,7 +827,7 @@ def validate_timeout(new_validate_timeout = NOT_CONFIGURED)
elsif defined?(@validate_timeout)
@validate_timeout
else
find_inherited_value(:validate_timeout)
find_inherited_value(:validate_timeout) || 3
end
end

Expand Down
20 changes: 20 additions & 0 deletions spec/graphql/schema_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -604,4 +604,24 @@ def test
assert_equal expected_errors, schema.execute(query_str).to_h['errors']
end
end
describe ".validate_timeout" do
it "provides a default timeout when not explicitly set" do
schema = Class.new(GraphQL::Schema)
assert_equal 3, schema.validate_timeout
end

it "allows overriding the default timeout" do
schema = Class.new(GraphQL::Schema) do
validate_timeout 15
end
assert_equal 15, schema.validate_timeout
end

it "allows disabling the timeout" do
schema = Class.new(GraphQL::Schema) do
validate_timeout nil
end
assert_nil schema.validate_timeout
end
end
end
Loading