-
Notifications
You must be signed in to change notification settings - Fork 409
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
[BUG] Tapir oneOf
generates unexpected behavior of generated sttp client
#2354
Comments
What's interesting if client models only single error like that: val findOrderWithSingleError: Endpoint[String, String, NotFound.type, Order, Any] =
endpoint.get
.securityIn(auth.bearer[String]())
.in("order")
.in(path[String]("id"))
.out(jsonBody[Order])
.errorOut(
oneOf(
notFoundStatus
)
) then 404 would be handled well by the client. Only adding another |
That's right! The example repository is now updated to reflect that situation. As you can see in the run output below, the client properly handles the |
The problem was due to content negotiation implementation - if some of the variants specified a body (with a content-type), and some didn't there was a pre-filtering step which removed the variants without the body. Now these variants are preserved. |
TL;DR I think I've found a bug in how Tapir generates client behavior based on
OneOfVariant
used. The following repository reproduces the issue https://github.com/majk-p/oneof-tapir-demoTapir versions tested: 1.0.1, 0.19.x
Scala version: 2.13.8
Background
2 teams, one provides a service, and the other uses it over https. Both use tapir. The client models the server endpoint on its own and generates a client out of the sources (each team has its own code repository).
Goal
On the server side create an endpoint
GET /order/:id:
thatThe client wants to model that endpoint regardless of the way it's implemented on the server. Especially the client team doesn't need to know anything more than the error code in terms of error modeling.
The problem
Let's say the server implements the endpoint following way:
where
and the client goes with:
where
So the difference is clearly only about how we define the matcher.
When we generate the client out of the client
findOrder
and try to execute it against the server, in the case when we ask for non-existingOrder
. The request ends withDecodeResult.Failure
ofMismatch(403,404)
. This seems like the client was expecting403
but received404
.With the
notFoundStatus
definition I'd expect that the client would check if the status code matches, and if it does - it should match.I've prepared the full example available at https://github.com/majk-p/oneof-tapir-demo. If you run that code you'll get the following output:
I would expect this would work that this third example works exactly like the second one.
My questions are:
The text was updated successfully, but these errors were encountered: