rescue_from handler return values during argument coercion are passed to resolve as the argument's value
Maintainer thường phản hồi trong vòng 1 ngày
Một pull request liên quan đã được merge.
- #5837 của @austinjb32 — đã merge
Đánh giá
- Độ khó
- 3/5
- Thời gian dự kiến
- 1-2 ngày
- Mức phù hợp với người mới
- 58/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- ruby
- Lĩnh vực
- backend-api-design
Hướng nghiên cứu
Start in Schema::Argument#coerce_into_values and trace the three handle_or_reraise call sites, then check how coerce_arguments and Runtime#evaluate_selection_with_args handle errors. Reproduce with the provided schema and argument validation example. Done means a returned GraphQL::ExecutionError reaches the response as the expected error and the resolver does not receive it as an argument; add a regression test for that behavior.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Describe the bug
When an error is raised during argument coercion — e.g. an argument validates: check failing inside Schema::Argument#prepare_value — the error is routed through handle_or_reraise, and the schema's rescue_from handler's return value is stored as the argument's value. If the handler returns a GraphQL::ExecutionError (a very common pattern), that error object is passed to the field's resolver as the argument value instead of short-circuiting resolution with the error.
Runtime#evaluate_selection_with_args only short-circuits when resolved_arguments itself is an ExecutionError/UnauthorizedError — errors nested inside the Arguments object sail through.
Versions
graphql 2.6.13 (also reproduced on 2.5.11)
Steps to reproduce
require "graphql"
class LeakySchema < GraphQL::Schema
# Common pattern: rescue_from returns (rather than raises) an error object
rescue_from(StandardError) do |err, _obj, _args, _ctx, _field|
GraphQL::ExecutionError.new(err.message)
end
class Query < GraphQL::Schema::Object
field :check, Integer, null: true do
argument :limit, Integer, validates: { numericality: { within: 1..50 } }
end
def check(limit:)
limit + 1
end
end
query(Query)
end
pp LeakySchema.execute("{ check(limit: 0) }").to_h
Expected behavior
{"errors" => [{"message" => "limit must be within 1..50", ...}], "data" => {"check" => nil}}
Actual behavior
resolve receives the GraphQL::ExecutionError instance as limit, so limit + 1 raises NoMethodError, which the handler then converts into a misleading error:
{"errors" => [{"message" => "undefined method '+' for an instance of GraphQL::ExecutionError", ...}]}
Without any rescue_from handler, the error reraises and surfaces correctly — so this only reproduces on schemas that register a handler which returns an error object. (It also makes the behavior environment-dependent if the handler is registered conditionally, e.g. only outside development.)
Diagnosis
Schema::Argument#coerce_into_values rescues coercion errors via context.schema.handle_or_reraise(context, err) at all three call sites (type.coerce_input, prepare_value, load_and_authorize_value) and assigns the return value as the argument value:
prepared_value = begin
prepare_value(parent_object, resolved_coerced_value, context: context)
rescue StandardError => err
context.schema.handle_or_reraise(context, err) # <= a returned error object lands here
end
coerce_arguments correctly handles raised errors (finished_args = err → continue_value), but nothing handles handler-returned ones.
Possible fix
Re-raise the handled result when it's an error object, so coerce_arguments short-circuits with it — I've got a working branch with a failing test + fix here if useful: https://github.com/austinjb32/graphql-ruby/tree/fix-argument-validation-error-leak
Additional context
Same bug family as the historical prepare:-returns-error leak (#1024).
- Ngôn ngữ chính
- Ruby
- Star
- 5.4k
- Fork
- 1.4k
- Merge trung bình
- 1 ngày 8 giờ
- Pull request đã merge (30 ngày)
- 74
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của rmosolgo/graphql-ruby
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
rmosolgo/graphql-ruby#5843 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 55/100
rmosolgo/graphql-ruby#5763 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 45/100
rmosolgo/graphql-ruby#5761 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 52/100
rmosolgo/graphql-ruby#5707 · 10 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 30/100
rmosolgo/graphql-ruby#5655 · 4 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của rmosolgo/graphql-ruby
Issue tương tự
-
account: profile bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 5 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
metanorma/metanorma-standoc#1315 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
metanorma/metanorma-iso#1681 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
Maintainer thường phản hồi trong vòng 1 ngày