-
Notifications
You must be signed in to change notification settings - Fork 658
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
Deprecate ApolloCompositeException with Error level and use suppressed exceptions instead #4062
Comments
Hi ! 👋100% agree the exception handling could use some more ergonomic APIs. Not 100% about this specific case though. Mutations typically do not hit the cache so I don't think you should get an |
Ah, I see. I just wrote some random example, by using my imagination. So it probably only happens for querying then 🙂 |
I see 👍. For queries, the problem happens if you have both a network and a cache error. The caller might want to have access to the cache miss error fir an example. If you're not using the cache, you can simply ignore |
I intend to use caching, so this exception is still relevant for me. Is composite exception there only because of cache-miss? What if you exposed some sort of callback for cache-miss instead? Like cache-miss "interceptor", or smth along those lines? |
Yes, mostly
Let's say you're doing a CacheFirst query that fails because both cache and network fail. What exception would you expect there? |
In case of "cache miss callback", I'd say network exception. But hm, in case of NetworkFirst this might get weird. Would it be possible to rather limit When I first try to handle this exception, I had no clue what I can get in Hope you can see where I'm coming at :) |
I 100% see the pain point there. Something we can do for sure is update the documentation (see #4065)
We can't do that because // A helper function that returns the [suppressedExceptions] as a list of [ApolloException]
val suppressedApolloExceptions: List<ApolloException>. Would that help? Also ping @BoD @akshay253101 since we had a related discussion in #3957, do you have any opinion on this? |
In my opinion, yes, a Just for the sake of the argument (as we can't really change this now) I think the ideal would have been:
|
From my pov, this would definitely better message what you can expect to handle. It would even better if we could somehow guarantee, that |
ApolloCompositeException takes first and second exception as Throwable and added to suppressedException, So in constructor we can restrict it to ApolloException |
This we do already, right?
I like this !
Maybe we can? It's a behaviour change but also kind of an edge case so it should be transparent for the vast majority of users ? And it's not API/ABI breaking so there's no risk of a runtime exception from a transitive usage or such things. For @akshay253101 use case (getting the network error from a Http if (exception is ApolloCompositeException) {
// get the network error
exception.suppressedExceptions[0] as? ApolloException
} to if (exception.suppressedExceptions.isNotEmpty()) {
// get the network error
exception.suppressedExceptions[0] as? ApolloException
} |
✅ Changing the type of exception thrown would require clients who handle it to update the But it's true at least it shouldn't make the code crash - and of course we would clearly warn of the behavior change in the changelog. Might be a bit annoying in the short run, on the other hand this would allow deprecating |
Hm, I also like the idea. I'm worried how annoying would it be to go "down the rabbit hole" to find exception, that you're looking for. Maybe some sort of helper method would make it bearable. I guess it's not that bad, since it's only 2 atm. But it's again hard to predict how to handle it. |
Maybe we deprecate |
Totally 👍
Agreed as well |
Fixed with #4718 I wend with throwing the first exception and adding all later ones as suppressed, similar to what would happen with |
Use case
I'm finding
ApolloCompositeException
annoying to handle. It contains multiple exceptions and you kind of have to pick one exception, and based on it show error message to user. Along side that, you have to potentially handle and report all other errors (e.g. Firebase).For example:
Describe the solution you'd like
I may be missing some context, why it was designed in such a manner. But ideally, I would prefer smth like:
The text was updated successfully, but these errors were encountered: