-
Notifications
You must be signed in to change notification settings - Fork 3
[CDX-358] Suppress undeliverable RxJava errors #158
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
base: master
Are you sure you want to change the base?
[CDX-358] Suppress undeliverable RxJava errors #158
Conversation
Code Review SummaryThis PR introduces a global RxJava error handler to prevent app crashes from undeliverable exceptions (specifically network timeouts like Detailed FeedbackPositive Aspects
Issues and Concerns[File: The code calls private fun setupRxErrorHandler() {
// Check if handler is already set to avoid conflicts
if (RxJavaPlugins.getErrorHandler() == null) {
RxJavaPlugins.setErrorHandler(createRxErrorHandler())
}
}However, there's a deeper architectural concern: RxJavaPlugins are global singletons. If your library sets a global error handler, it could conflict with:
Recommendation: Document this limitation clearly in the KDoc and consider alternative approaches like wrapping observables with proper error handling operators instead of global handlers. [File: The error unwrapping logic internal fun createRxErrorHandler(): (Throwable) -> Unit = { throwable ->
val error = throwable.cause ?: throwable
when (error) {
is IOException, is InterruptedException -> {
// Network errors and interruptions are expected in normal operation
e("Non-fatal network error: ${error.javaClass.simpleName}: ${error.message}")
}
else -> {
// For unexpected errors, include stack trace for debugging
e("Undeliverable exception: ${error.javaClass.simpleName}: ${error.message}")
error.printStackTrace()
}
}
}This improvement:
[File: The KDoc for /**
* @property suppressRxErrors When true, sets up a global RxJava error handler to catch
* undeliverable network exceptions (e.g., SocketTimeoutException) that would otherwise crash
* the app. Defaults to false.
*
* **Important**: This sets a global RxJava error handler which may conflict with error
* handlers set by the host application or other libraries. Only enable this if you are
* experiencing crashes from undeliverable RxJava exceptions.
*
* **Recommended**: Instead of enabling this flag, consider handling errors properly in
* your RxJava subscription chains using operators like `onErrorReturn()` or `doOnError()`.
*/[File: The test wraps the internal handler with a counting mechanism, but this means you're not actually testing the production error handler directly. Consider: @Before
fun setup() {
RxJavaPlugins.reset()
errorCount = 0
RxJavaPlugins.setErrorHandler(ConstructorIo.createRxErrorHandler())
}
// Add a RxJavaPlugins error handler wrapper that counts for assertions
private fun setupCountingHandler() {
val productionHandler = ConstructorIo.createRxErrorHandler()
RxJavaPlugins.setErrorHandler { throwable ->
errorCount++
productionHandler(throwable)
}
}Then use [File: Consider adding tests for:
[General] - Architecture: Consider alternative approach The root cause of undeliverable exceptions is typically improper subscription management or missing error handling in Observable chains. Instead of a global error handler, consider:
fun <T> Observable<T>.withErrorHandling(): Observable<T> {
return this.doOnError { error ->
if (error is IOException || error is InterruptedException) {
e("Network error: ${error.message}")
}
}.onErrorResumeNext(Observable.empty())
}This approach is more localized, doesn't create global side effects, and gives developers more control. [General] - Documentation: Missing integration guide There's no documentation about when and why developers should enable ConclusionThe implementation is functionally correct and well-tested, but the use of a global RxJava error handler is architecturally concerning due to potential conflicts with the host application and other libraries. Recommendations:
If the team decides to proceed with this approach, I recommend making the improvements to error handling, documentation, and adding the conflict check before merging. Overall assessment: Changes Requested - The code works as intended, but architectural concerns and missing safeguards should be addressed before merging. |
No description provided.