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

[BUG] impossible to create an infallible header #4272

Closed
Angel-O opened this issue Jan 16, 2025 · 2 comments · Fixed by #4273
Closed

[BUG] impossible to create an infallible header #4272

Angel-O opened this issue Jan 16, 2025 · 2 comments · Fixed by #4273

Comments

@Angel-O
Copy link

Angel-O commented Jan 16, 2025

Tapir version: 1.11.11

Scala version: 2.13.5

Describe the bug

I'd like to define an optional header with underlying String schema without any particular validation.
Since it's optional and it doesn't have any validation, I don't want the generated docs to report a possible 400 error.

Unfortunately it doesn't seem to be possible

What is the problem?

I believe the problem is caused by a clash on the conditions set on this line

case i: EndpointInput.Atom[_] => decodingMayFail(i.codec) || !i.codec.schema.isOptional

in particular inside decodingMayFail (1st condition)

codec.schema.schemaType != SchemaType.SString()

and on line 25 (2nd condition)

!i.codec.schema.isOptional

The problem is that if the header is optional the predicate on line 25 will be true because the first condition will be true and if the header is a string the predicate will fail because the schema will be a Schema[String], rather than an Schema[Option[String]] (so the second condition .isOptional will be false and its negation will be true). So it appears that these conditions are clashing: i.e. they can't be false at the same time, which is what I would like

Note: I tried to modify Schema this way

Schema[String].schema(_.copy(isOptional = true))

and that fixes the documentation problem, but raises an error when calling the endpoint without the header because it's mandatory

How to reproduce?

  • create a minimal endpoint (GET request) with an optional string header that doesn't have any validation
  • generate docs

expected result:

  • documentation shouldn't report a possible 400 error

actual result:

  • documentation shows a 400 error

Maybe you can provide code to reproduce the problem?

val ep: Endpoint[...] = ???
ep.in(header[Option[String]]("some-header"))

Additional information

  • I've customised my endpoint building logic so the issue may be caused by something else (apologies in that case), but if that's indeed the problem I'd be happy to take a look and see if I can fix it 🙏🏾
  • on a side note, some of the logic to customise the autogenerated docs is behind private methods (i.e. decodingMayFail): would it make sense to make them public so that they can be used in client code outside of the library ?
@adamw
Copy link
Member

adamw commented Jan 16, 2025

See the linked PR. It's a heuristic, so it never will be perfect, but now it should be a bit better.

As for private methods - each method that's made public becomes harder to refactor, part of the public contract. Even though we guarantee bincompat only for core, still I try to minimise the surface area and changes to public interfaces.

@Angel-O
Copy link
Author

Angel-O commented Jan 16, 2025

ok, thanks for the speedy fix.

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 a pull request may close this issue.

2 participants