-
Notifications
You must be signed in to change notification settings - Fork 130
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
Strict parsing of JSON response results in uncaught exceptions #464
Comments
@bryfox thanks for the report. Although this applies to a crafted and unexpected response, have you come across a valid use case where the server would return an empty object? |
Not under normal conditions, but we experienced a number of crashes in production during a short burst of high traffic for this reason. This app has not yet been updated to v2, but faces a similar situation:
|
In the first comment, you point to a commit from the branch main (v2). However, above you say you have not yet migrated to v2. Can you please clarify in which version you are observing this issue? Also, I'm trying to pinpoint the endpoint that was used. Have you seen any interesting logs on the Auth0 dashboard when this happened? We should handle this scenario and fail through the provided callback as you suggest. But would like to understand how to reproduce this without intercepting the server response. |
Sorry for the confusion! In our production app, we're using Lock, and the corresponding version of this SDK (with a couple of minor customizations we made, but that shouldn't matter for this discussion). Given the recent v1 deprecation, I wanted to see if this will still be an issue with v2; I have reproduced with the v2 sample app only by proxying the response. Unfortunately, I can't see back that far in the Auth0 logs (> 2 days). Our web clients also reported error responses from the same timeframe — 503 and 429 status codes, in case that's of help in narrowing down the behavior. |
@bryfox I came back to this today. To summarize your situation as I understand it (please confirm), you are currently using Lock.Android v2 and Auth0.Android v1 (comes as a dependency from Lock). Your users often run into exceptions when parsing an error using the from(Map) method from the SDK v1; which is why you opened this in the first place. You said you tried making Lock use the SDK v2 and you still run into this scenario. May I ask how you are making it use the SDK v2? Because the stack trace above is really specific to v1. The class If you have a stack trace for v2 that you can share it will help us debug this behavior. Kotlin enforces nullability checks so it should be fairly easy to spot, but the compiler doesn't warn us of anything today. |
Your initial summary is mostly correct, except that this happened only very rarely. There were a number of users affected, but all crashes occurred within the span of a minute, during an unusual spike in traffic. We saw a similar burst in traffic a week later, and a similar number of crashes; otherwise, I don't believe we ever encountered this. I haven't yet done anything with Lock and SDK v2. With v2, I only used the Here are the basic steps I took for that synthetic test (forcing an empty response body)... In order to MITM responses, I updated
Note if I leave the response status as successful, then the
|
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you have not received a response for our team (apologies for the delay) and this is still a blocker, please reply with additional information or just a ping. Thank you for your contribution! 🙇♂️ |
@bryfox I still didn't encounter the scenario in which the server responded with an empty string response and we were expecting something different. I haven't played with proxying the request and changing the response. But I've been doing some research to try to narrow this down and see if we can cover it anyways. This is what I found. Gson, the JSON library we use to deserialize the responses from the server, has different ways of deserializing JSON. Aparently, using Using // ### Without a custom deserializer
// returns null
gson.fromJson(" ", String::class.java)
// throws java.io.EOFException
gson.getAdapter(String::class.java).fromJson(" ")
// ### With a custom deserializer
// returns null
gson.fromJson(" ", Credentials::class.java)
// returns null
gson.getAdapter(Credentials::class.java).fromJson(" ") Even when we have code in our custom deserializers (adapters) that would assert for empty or invalid input, that never gets called because Gson checks the input before invoking the adapter. See the But, according to this comment, we should be implementing I guess it could be a good idea to explore checking if the Do you have any other ideas that we could try? Cheers |
@lbalmaceda I'm no longer working on the app that uses this library, but it looks like you now handle the Sounds like you're being cautious and looking to handle the |
@bryfox Coming back to this after some days. 👋 Thanks for your suggestion. According to that, I should be stopping a potentially null value from even reaching the "success callback". And with the context in this issue thread, that would be for successful responses from the server (status code 200). So basically, take this line and change it to check the output value is NOT null before returning it. Otherwise, throw an exception (i.e parsing exception). However, we would be "failing the request" after a successful server response. Don't get me wrong, I think that's better than getting an unhandled runtime exception. Still, the I'm open to improving this JSON parsing logic, but I think we already invested quite a time in fixing the SDK for a use case that we couldn't even reproduce with the existing endpoints. I'll close this issue for now assuming that the PR you linked already fixed this use case, but I'm happy to re-open it if a valid use case that reproduces this is found. Thanks for sticking with the conversation. 🏅 |
Describe the problem
When a server sends an invalid JSON response (for example, an empty body); the response parsing throws an exception and crashes the sample app.
What was the expected behavior?
It would be nice to be more lenient about an invalid response, and propagate it (or something relevant) in the
onFailure
callback.Reproduction
/oauth/token
:Environment
The text was updated successfully, but these errors were encountered: