I'm calling an API which throws 404 status code and due to that app gets crashed. The code snippet is mentioned below:
fun loadAndSavedata(
type: Type,
bookmark: String? = null,
): Single<MetaData> {
return loadFilesByType(type, bookmark)
.map { response ->
if (!response.isSuccessfulAndHasBody()) {
//This line gets pointed as cause
throw OfflineModeException(response)
}
response.body()!!
}
.flatMap { loadNextPages(it, type) }
}
The error, I receive in logcat is:
Process: com.example.app, PID: 23797
io.reactivex.rxjava3.exceptions.UndeliverableException: The exception could not be delivered to the consumer because it has already canceled/disposed the flow or the exception has nowhere to go to begin with. Further reading: https://github.com/ReactiveX/RxJava/wiki/What's-different-in-2.0#error-handling | com.com.example.app.models.OfflineModeException: HTTP 404
at io.reactivex.rxjava3.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:367)
at io.reactivex.rxjava3.internal.operators.single.SingleZipArray$ZipCoordinator.innerError(SingleZipArray.java:139)
at io.reactivex.rxjava3.internal.operators.single.SingleZipArray$ZipSingleObserver.onError(SingleZipArray.java:175)
at io.reactivex.rxjava3.internal.operators.single.SingleFlatMap$SingleFlatMapCallback.onError(SingleFlatMap.java:91)
at io.reactivex.rxjava3.internal.operators.single.SingleFlatMap$SingleFlatMapCallback.onError(SingleFlatMap.java:91)
at io.reactivex.rxjava3.internal.operators.single.SingleFlatMap$SingleFlatMapCallback.onError(SingleFlatMap.java:91)
at io.reactivex.rxjava3.internal.operators.single.SingleFlatMap$SingleFlatMapCallback.onError(SingleFlatMap.java:91)
at io.reactivex.rxjava3.internal.operators.single.SingleMap$MapSingleObserver.onError(SingleMap.java:70)
at io.reactivex.rxjava3.internal.operators.single.SingleMap$MapSingleObserver.onSuccess(SingleMap.java:61)
at io.reactivex.rxjava3.internal.operators.observable.ObservableSingleSingle$SingleElementObserver.onComplete(ObservableSingleSingle.java:110)
at io.reactivex.rxjava3.internal.operators.observable.ObservableSubscribeOn$SubscribeOnObserver.onComplete(ObservableSubscribeOn.java:68)
at retrofit2.adapter.rxjava3.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:52)
at io.reactivex.rxjava3.core.Observable.subscribe(Observable.java:13095)
at io.reactivex.rxjava3.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96)
at io.reactivex.rxjava3.core.Scheduler$DisposeTask.run(Scheduler.java:589)
at io.reactivex.rxjava3.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:65)
at io.reactivex.rxjava3.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:56)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:920)
Caused by: com.com.example.app.models.OfflineModeException: HTTP 404
Can anyone please guide me how I can handle this error and avoid crash?
throw OfflineModeException(response)
// you are explicitly throwing exception on unsuccessful response. Remove this line or add a try catch block
You can not use throw directly because map function accept functional Interface Function<T,R>. In Function<T,R> abstract method is R apply(T t) so in apply function no throws present so you can not use throw keyword without try catch block
in map.
Related
Is there any way to get an exception response when calling suspended function?
Here is my solution but this is not working as I expected.
private fun mockServiceResponse() = service.stub {
onBlocking { loadMessages(Mockito.any() ?: createInstance()) }
.thenThrow(SocketException::class.java)
}
The test fails with the following error message.
Checked exception is invalid for this method!
Invalid: java.net.SocketException
org.mockito.exceptions.base.MockitoException:
will work if I replace thenThrow(SocketException::class.java)}
with thenAnswer { throw SocketException() }
I am trying to call data from Firebase and map it to data class while using MVVM but Its showing me errors saying failed to Connect
The code of Repository Implementation:
override suspend fun uploaded_docs_retrival(): ArrayList<String> {
return try {
val result = Firebase.firestore.collection("users").whereEqualTo("UID", "84HMm1MJx8X8G33i7sxqUKQLzTn2").get()
.await()
result.first().toObject(docretreving::class.java).Docs
} catch (e: Exception) {
Log.e("TAG", "Failed to upload: ${e.message.orEmpty()}")
ArrayList()
}
}
Code of View Model:-
val livedata : MutableLiveData<ArrayList<String>> by lazy
MutableLiveData<ArrayList<String>>()
fun uploaded_docs_retrival() {
viewModelScope.launch(Dispatchers.IO){
livedata.postValue(repository.uploaded_docs_retrival())
}
}
I am trying to call the function from View Model and the error I am seeing is:
W/Firestore: (24.0.1) [WatchStream]: (297224f) Stream closed with status: Status{code=INTERNAL, description=error in frame handler, cause=java.lang.NoSuchMethodError: No interface method getBuffer()Lokio/Buffer; in class Lokio/BufferedSource; or its super classes (declaration of 'okio.BufferedSource' appears in /data/app/~~zy8Sr4ZK3BufSuP5iCevdQ==/com.example.alliaiseV1-OysKU8xYFaKtBxHIS_ndvw==/base.apk!classes15.dex)
at io.grpc.okhttp.OkHttpClientTransport$ClientFrameHandler.data(OkHttpClientTransport.java:1144)
at io.grpc.okhttp.internal.framed.Http2$Reader.readData(Http2.java:234)
at io.grpc.okhttp.internal.framed.Http2$Reader.nextFrame(Http2.java:147)
at io.grpc.okhttp.OkHttpClientTransport$ClientFrameHandler.run(OkHttpClientTransport.java:1103)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:923)
}.
W/Firestore: (24.0.1) [OnlineStateTracker]: Could not reach Cloud Firestore backend.
Connection failed 1 times. Most recent error: Status{code=INTERNAL, description=error
in frame handler, cause=java.lang.NoSuchMethodError: No interface method
getBuffer()Lokio/Buffer; in class Lokio/BufferedSource; or its super classes
(declaration of 'okio.BufferedSource' appears in
/data/app/~~zy8Sr4ZK3BufSuP5iCevdQ==/com.example.alliaiseV1-
OysKU8xYFaKtBxHIS_ndvw==/base.apk!classes15.dex)
at io.grpc.okhttp.OkHttpClientTransport$ClientFrameHandler.data(OkHttpClientTransport.java:1144)
at io.grpc.okhttp.internal.framed.Http2$Reader.readData(Http2.java:234)
at io.grpc.okhttp.internal.framed.Http2$Reader.nextFrame(Http2.java:147)
at io.grpc.okhttp.OkHttpClientTransport$ClientFrameHandler.run(OkHttpClientTransport.java:1103)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:923)
}
This typically indicates that your device does not have a healthy Internet connection at the moment. The client will operate in offline mode until it is able to successfully connect to the backend.
E/TAG: Failed to upload: Collection is empty.
The TAG in last line of error Indicates I am getting a Exception in My Repository Function Which is the First Function of this Question Mentioned Above.
However if I modify the Function to below and I don't use View Model and Directly Code the Function below in the Fragment and check the Logcat it is Retrieving perfectly
Altered Trying Code:
suspend fun uploaded_docs_retrival(): ArrayList<String> {
return try {
val result = Firebase.firestore.collection("profiles").whereEqualTo("UID", "YHMauLouORRtrYBV2h4dHJ5A0s72").get()
.await()
result.first().toObject(docretreving::class.java).Docs
} catch (e: Exception) {
Log.e("TAG", "Failed to upload: ${e.message.orEmpty()}")
ArrayList()
}
}
lifecycleScope.launch {
val z = uploaded_docs_retrival()
Log.d("Cross","$z")
}
How can the same Code work and if I use View Models and Live Data It crashes.
Help would be Appreciated , Been a quite While I am stuck with this.
Thanks in Advance
Looks like a library is missing. Try adding:
implementation("com.squareup.okhttp3:okhttp:4.9.3")
I am using Retrofit with coroutines (built in support). I have a Retrofit interface, retrofit implementation and the API implementation created by Retrofit, but it doesn't matter as it doesn't get called. It crashes before that, here:
In XService.kt
suspend fun test() {
val mediaType = MediaType.parse("text/plain")
val requestBody = RequestBody.create(mediaType, "TEST STRING") // Crashes here
// Now make some network requests
}
which is called by a viewModel:
suspend fun test() {
return withContext(viewModelScope.coroutineContext) {
service.test()
}
}
which is called by a Fragment:
lifecycleScope.launch() { model.test() }
Unhelpful error:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: package_name, PID: 9729
I/Process: Sending signal. PID: 9729 SIG: 9
I'm just not sure why creating a RequestBody causes a crash. What is weird is, when debugging and going slowly through the code, it doesn't crash... I have simplified the code so its easier for you to read, but the reason why its scoped to Fragment, not VM is because I want the Fragment to change the UI based on the response.
EDIT: It turns out if I wrap it in a try/ catch block, the line which crashes usually doesn't crash. Instead, the network call afterwards does, giving printing out:
I/System.out: java.net.UnknownHostException: Unable to resolve host "qats.orth.uk": No address associated with hostname
try {
val requestBody = RequestBody.create(mediaType, mode.toString())
return api.createQuiz(requestBody).createResult()
} catch (e: Exception) {
println(e)
}
So I am confused. Why does putting it in a try/catch block change what error message I get. Without try/catch, I got a useless crash with no stacktrace. I guess this may be the challenge with coroutines.
So, I am getting an error in my Android app (Kotlin) when trying to subscribe to a PublishSubject.
The error explanation is pretty straight forward, however, I have failed trying to implement this, onError function and I am not sure how to do it in a god way.
Here the error
The exception was not handled due to missing onError handler in the subscribe() method call. Further reading: https://github.com/ReactiveX/RxJava/wiki/Error-Handling | com.androidnetworking.error.ANError
Here the PublishSubject:
var positionSubject = PublishSubject.create<Location>()
Here when I subscribe (which gives error inside the code of the subscription):
compositeDisposable.add(
positionSubject.subscribe {
// do some actions here that causes Exception
}
)
Here my attempt to fix it in a "nice" way (did not work, still crashes in subscribe):
compositeDisposable.add(
positionSubject
.onErrorReturn { t ->
Log.d("debug", "EXCEPTION OCCURRED")
Location("")}
.subscribe {
// do some actions here that causes Exception
}
)
Here what I ended up doing to fix it and not crashing:
compositeDisposable.add(
positionSubject.subscribe {
try{
// do some actions here that causes Exception
}catch(e:Exception){
Log.d("debug", "EXCEPTION OCCURRED $e")
}
}
)
I am wondering how to this in a cleaner way than using the try/catch block inside the subscribe, if it is even possible.
Following code is kotlin way to subscribe a PublishSubject
var positionSubject = PublishSubject.create<Location>()
positionSubject.subscribe({ location ->
}, { error ->
})
This should work fine.
I was trying to make an API request inside a Kotlin Coroutines. I have wrapped all code inside the coroutine with a try-catch block.
viewModelScope.launch {
try {
val temp = repository.searchMatch(query ?: "")
liveData.postValue(temp)
} catch (e: Exception) {
Log.d(TAG, e.message.toString())
}
}
The problem is, if I turning off the network while the request still running, the exception gets caught but also my app gets crashed because of the uncaught exception.
This is the uncaught exception I got:
android.system.ErrnoException: read failed: ENETDOWN (Network is down)
at libcore.io.Linux.readBytes(Native Method)
at libcore.io.Linux.read(Linux.java:184)
at libcore.io.BlockGuardOs.read(BlockGuardOs.java:254)
at android.system.Os.read(Os.java:414)
at android.net.util.PacketReader.readPacket(PacketReader.java:137)
at android.net.util.PacketReader.handleInput(PacketReader.java:207)
at android.net.util.PacketReader.access$100(PacketReader.java:70)
at android.net.util.PacketReader$1.onFileDescriptorEvents(PacketReader.java:189)
at android.os.MessageQueue.dispatchEvents(MessageQueue.java:285)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:326)
at android.os.Looper.loop(Looper.java:165)
at android.os.HandlerThread.run(HandlerThread.java:65)
2020-08-13 23:48:49.326 1205-5265/? E/MtkDhcpClient: Read error
android.system.ErrnoException: read failed: ENETDOWN (Network is down)
at libcore.io.Linux.readBytes(Native Method)
at libcore.io.Linux.read(Linux.java:184)
at libcore.io.BlockGuardOs.read(BlockGuardOs.java:254)
at android.system.Os.read(Os.java:414)
at com.mediatek.net.dhcp.MtkDhcpClient$ReceiveThread.run(MtkDhcpClient.java:434)
I have tried to set a CoroutineExceptionHandler and use a SupervisorJob but nothing works.
Please help me!