-
Notifications
You must be signed in to change notification settings - Fork 19
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
Encode NaN as null #2
Conversation
Circe does not allow to encode `Double.NaN` as a JSON number, which is compliant with the JSON spec where no `NaN` keyword exists. However, Circe supports encoding `Double.NaN` as `null` and assuming that users of the Circe marshaller is aware of this, it seems to be a better tradeoff than having the Sangria Circe marshaller throw a "None.get" exception.
I also wonder if the testkit should include a test for |
Thanks a lot for pointing this out! I completely missed this aspect. My main concern is that introducing this behavior will violate GraphQL spec. I just double-checked other implementations (e.g. spray-json) and they indeed return Main issue is that even for non-null GraphQL
This would mean that it should be handled by the main library. Doing in a I prepared a PR that will implement this behavior: https://github.com/sangria-graphql/sangria/pull/167/files What do you think? |
jsonString = Some(_), | ||
jsonArray = _ => None, | ||
jsonObject = _ => None | ||
).getOrElse(throw new IllegalStateException(s"$node is not a scalar value")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this change!
My concern is that it has unnecessary boxing in Option
, though current version has it as well. getScalarValue
would be is call for every scalar value in the input, so I think it would be better to avoid boxing in this case.
What do you think about something like this?
def getScalarValue(node: Json) = {
def invalidScalar = throw new IllegalStateException(s"$node is not a scalar value")
node.fold(
jsonNull = invalidScalar,
jsonBoolean = identity,
jsonNumber = num ⇒ num.toBigInt orElse num.toBigDecimal getOrElse invalidScalar,
jsonString = identity,
jsonArray = _ ⇒ invalidScalar,
jsonObject = _ ⇒ invalidScalar
)
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this looks more optimized.
case v: Float ⇒ Json.fromDouble(v).get | ||
case v: Double ⇒ Json.fromDouble(v).get | ||
case v: Float ⇒ Json.fromDoubleOrNull(v) | ||
case v: Double ⇒ Json.fromDoubleOrNull(v) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even if we merge sangria-graphql/sangria#167, I think we can use fromDoubleOrNull
here anyway. Main library will ensure that NaN and infinity will not reach this point, but at least we can avoid boxing (which fromDouble
does).
I'm not that familiar with the GraphQL specification. Will sangria-graphql/sangria#167 require that such values are filtered before passing them to Sangria? |
yeah, otherwise you will get an error. If not handled, they would be generic internal server errors. |
As long as there would be a way to tell sangria to ignore them? I'd hate to have to clean the data up front. For example we use Spark to read data we don't necessarily control from big query and S3 and serialize it to case classes. Having the ability to log the violations as warnings and fix them we go along would be preferable. |
I see, I started to wonder where you get all these You can always define a custom scalar type which will use the old unsafe behavior (with additional warning log). Though you need to consider the consequences - clients may get In As soon as you give an invalid WDYT? Will it be possible in your case? |
Yes, sure, that works. Right now I only have a handful. I will update the PR with your suggestions. |
A small cleanup to avoid explicit type checking and simplify error handling.
43fe743
to
b4f96cd
Compare
While migrating from the Spray JSON marshaller to Circe I experienced the following error:
I think it would be better to adopt Circe's encoding for NaN since users of the Circe marshalling library should be familiar with it.