-
Notifications
You must be signed in to change notification settings - Fork 428
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
juniper_warp::make_graphql_filter
improperly returns 4xx on some context_extractor
5xx errors
#1177
Comments
I'm having trouble understanding warp's filter model; possibly my
|
I personally haven't used warp so I will let other maintainers or community members chime in on this. |
@scottlamb sorry for responding late on this.
This behavior is definitely wrong. Especially, considering possible non-idempotent mutation semantics. It seems that we're missing |
@scottlamb upon further investigation, it seems that everything is relatively fine in
So, every time we return This exactly what happens in your example: let context_extractor: warp::filters::BoxedFilter<(Database,)> = warp::any().and_then(move || {
std::future::ready(if called.swap(true, std::sync::atomic::Ordering::Relaxed) {
println!("second call");
Ok(Database::new())
} else {
println!("first call");
Err(warp::reject::custom(MyRejection))
})
}).boxed(); Here, the To avoid switching to another However, we cannot write such let context_extractor: warp::filters::BoxedFilter<(Database,)> = warp::any()
.and_then(move || {
std::future::ready(if called.swap(true, std::sync::atomic::Ordering::Relaxed) {
println!("second call");
Ok(Database::new())
} else {
println!("first call");
Err(warp::reject::custom(MyRejection))
})
})
.recover(|rejection| {
// `MyRejection` should impl `warp::Reply`
// and `Clone`, because `find` returns `Option<&T>` only =(
rejection.find::<MyRejection>().cloned().ok_or(rejection)
})
.boxed(); In #1222 I'll describe this clearly in the docs and will provide an example. Also, regarding rejects inside |
- rework `make_graphql_filter()` and `make_graphql_filter_sync()` to execute `context_extractor` only once - handle all non-recoverable `Rejection`s in `make_graphql_filter()` and `make_graphql_filter_sync()` - relax requirement for `context_extractor` to be a `BoxedFilter` only - remove `JoinError` from public API - provide example of fallible `context_extractor` in `make_graphql_filter()` API docs Additionally: - split `juniper_warp` modules into separate files - add @tyranron as `juniper_warp` co-author
@scottlamb so, in the end, I've ended up rewriting |
Describe the bug
with
juniper_warp = "0.7.0"
, this sequence can happen:application/json
body.post_json_filter
runs;context_extractor
fails for some transient reason (database error in my case), returns someRejection
that should produce a 5xx error.post_graphql_filter
runs.context_extractor
happens to succeed this time.post_graphql_filter
returns a 4xx rejection about a parse error because the body's actually in json format.To Reproduce
Steps to reproduce the behavior:
(code example preferred)
failing unit test diff
Expected behavior
It should run my
context_extractor
only once per request. AnyRejection
s returned from thecontext_extractor
should be returned faithfully from the combined filter returned frommake_graphql_filter
, rather than effectively turning a 5xx error into a 4xx error.Additional context
Add any other context about the problem here.
The text was updated successfully, but these errors were encountered: