-
Notifications
You must be signed in to change notification settings - Fork 494
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
[Proposal] Global error handler for execute functions #535
Comments
@jakoss How would you propose failures would be detected. Reducers are opaque to Mavericks. We don't know what each one does and wouldn't be able to tell you where the error originated from either. re: Throwable. We could probably switch to that if it's causing issues. It just hasn't caused any issues (that we've heard of) yet. |
I wouldn't detect failure on reducer, just after it in execute functions:
and here:
We have Exception there. In my experience with android i had 2 situations with code that crashed on production (native library integration issue) just because i was catching Exception instead of Throwable. Since Throwable handles basically everything bad that can happen it might be safer, especially if user assumes that execute is totally safe in that regard |
This all sounds great to me, thanks for laying out a clear plan. Agree with
instead of Do you think there is any possibility of needing this for Success and/or Loading states too? If so we could make the callback interface have those too, or at least design the interface so they can be added later if needed (I maybe prefer the latter) |
So maybe an interface like this: interface AsyncEventsListener {
fun onSuccess(event: Success<*>) {}
fun onLoading(event: Loading<*>) {}
fun onFail(event: Fail<*>) {}
} Default method implementations might be handy if someone wants to listen only to one/two of events. I can go through the codebase and find all places that can emit Async events and invoke proper methods there. I can replace |
I'm worried that this could introduce some unexpected bugs. If somebody were to ever change an execute to a setOnEach, they would lose this functionality. Is that an acceptable tradeoff? |
If you can think of a more generic interface that would capture that use case though then all the better |
My original idea is to make Async more useful, I haven't considered other states. I'm not sure if there's a similar benefit from tracking everything from |
@elihart It doesn't inherently but it's not uncommon to use Async as an async result type outside of the context of execute. I'm still open to this but worried that somebody might do
At Tonal, some of our lower level data streams emit async so sometimes execute calls are converted to setOnEach. |
So maybe in
|
The only thing I care about is the exception and stack trace. I can do some experiments how it will look |
@jakoss That might be okay for your project but I'm worried that it doesn't work well for many/large apps. In many cases, generic IOExceptions from room/retrofit might not provide enough information to help debug an issue. |
I agree, I don't think it will give a lot of feedback. But it can be useful for example for error occurrence statistics, to issue an warning if errors are getting out of hand. It's not a powerful debug tool, just a hint that something might be wrong |
Other idea - maybe we can pass viewModel instance as a parameter for listeners? That can give a little bit of context. Or even allow to pass optional parameter to execute, something like |
Yes I think it would be good to pass the viewmodel reference to the listener. I suggested that in an earlier comment. I don't think I'm in favor of including debug information in the execute function. Instead you could have an extension function on Async that you invoke in your execute callback like It would be nice to automatically include context on the |
I have no more ideas here 😅 |
@jakoss You could also create a function in your own base view model like
|
Sure, I can solve this using extension if you don't see a value in global handler. No problem with that |
Maybe it's best to go with your own execute extension for now, and we can leave this proposal open to see if any other people weigh in with similar use cases. I'm still open to a global handler, but agree that the use case should be strong and the API should be flexible for different use cases |
Sure. And what about @gpeal How open adding |
I have the requirement to trace all errors in app, even if those are properly handled by the code and UI. So i need to create some global error handler for all
execute
function, that will be called onFail
reducer set. My proposal:Add new property to
MavericksViewModelConfig
with signature something like:I'm not sure that should be called handler, since it wouldn't have any impact on error handling, it's just for logging/tracing purposes. Maybe name
executeErrorLogger
would be more appropriate?Next, i'd add the same field to
MavericksViewModelConfigFactory
that would be passed down to configs.In
MavericksViewModel
i'd add callconfig.executeErrorHandler?.invoke(e)
aftersetState { reducer(Fail(e ...
for allexecute
functions.What do you think about that? If it's fine i'll create a PR with that.
Also, i have a minor question about error handling - is there a particular reason to catch
Exception
instead ofThrowable
?The text was updated successfully, but these errors were encountered: