I'm new to reactive programming and currently learning kotlin. I'm trying to make an API request using okhttp client but instead of using asynctask, I want to try rxjava.
fun network():Observable<String>{
val exe = Observable.create<String> { emitter->
emitter.onNext("https://pokeapi.co/api/v2/pokemon/500")
}
return exe.onErrorReturn{
it.toString()
}.subscribeOn(Schedulers.io()).flatMap {
val c = OkHttpClient();
val req = Request.Builder()
.url(it)
.build();
val resp = c.newCall(req).execute()
Observable.just(resp.toString())
}
I created a method with return type of observable string which will contain a string url from pokemon API and then I added a subscribeOn method which will force it to do the okhttpClient request be executed in the io thread (do in background equivalent of asynctask) then finally subscribe to it via simply calling the method in the onCreate of my activity:
network().subscribe {
Log.e("response",it);
}
Unfortunately im having the following error:
FATAL EXCEPTION: RxCachedThreadScheduler-1
io.reactivex.exceptions.OnErrorNotImplementedException: 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 | javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0xb955faf8: Failure in SSL library, usually a protocol error
error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:741 0x9da8e8c1:0x00000000)
at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:704)
at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:701)
at io.reactivex.internal.observers.LambdaObserver.onError(LambdaObserver.java:77)
at io.reactivex.internal.observers.BasicFuseableObserver.onError(BasicFuseableObserver.java:100)
at io.reactivex.internal.observers.BasicFuseableObserver.fail(BasicFuseableObserver.java:110)
at io.reactivex.internal.operators.observable.ObservableMap$MapObserver.onNext(ObservableMap.java:59)
at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeOnObserver.onNext(ObservableSubscribeOn.java:58)
at io.reactivex.internal.operators.observable.ObservableOnErrorReturn$OnErrorReturnObserver.onNext(ObservableOnErrorReturn.java:65)
at io.reactivex.internal.operators.observable.ObservableCreate$CreateEmitter.onNext(ObservableCreate.java:66)
at ui.activities.ObjectManipulation$network$exe$1.subscribe(ObjectManipulation.kt:37)
at io.reactivex.internal.operators.observable.ObservableCreate.subscribeActual(ObservableCreate.java:40)
at io.reactivex.Observable.subscribe(Observable.java:12267)
at io.reactivex.internal.operators.observable.ObservableOnErrorReturn.subscribeActual(ObservableOnErrorReturn.java:31)
at io.reactivex.Observable.subscribe(Observable.java:12267)
at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96)
at io.reactivex.Scheduler$DisposeTask.run(Scheduler.java:578)
at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:66)
at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:57)
at java.util.concurrent.FutureTask.run(FutureTask.java:234)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:153)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:267)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:856)
Caused by: javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0xb955faf8: Failure in SSL library, usually a protocol error
error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:741 0x9da8e8c1:0x00000000)
Line 37 in the error is the onNext(url).
Any useful hint or reply would be greatly appreciated!
At first it seems that the problem comes from the OkHTTP client configuration, you can check this to see how to fix it.
If you want that the app doesn´t crash you should handle the error by implementing onError when you are subscribing, you can find more information here.
Finally I would recommend you to use Retrofit instead of using raw OkHTTP. You can find an example here.
Related
I got following error :
javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x795c2a18: Failure in SSL library, usually a protocol error
error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:744 0x72728cfc:0x00000000)
The logs, in this case, are very weird. I am not able to figure out the issues that are causing the connectivity errors with the servers. Please help me out with this mpw 29503 error:
09-06 17:08:37.756 2285-4073/com.google.android.gms.persistent E/NetRec: [239] abno.a: Could not retrieve server token for package com.google.android.apps.gcs
java.util.concurrent.ExecutionException: mpw: 29503:
at alfn.b(:com.google.android.gms#12521024#12.5.21 (040700-189987672):4)
at alfn.a(:com.google.android.gms#12521024#12.5.21 (040700-189987672):28)
at abno.a(:com.google.android.gms#12521024#12.5.21 (040700-189987672):1)
at abno.a(:com.google.android.gms#12521024#12.5.21 (040700-189987672):7)
at abnl.getHeaders(:com.google.android.gms#12521024#12.5.21 (040700-189987672):2)
at com.android.volley.toolbox.HttpClientStack.performRequest(:com.google.android.gms#12521024#12.5.21 (040700-189987672):15)
at nmb.performRequest(:com.google.android.gms#12521024#12.5.21 (040700-189987672):1)
at bdb.executeRequest(:com.google.android.gms#12521024#12.5.21 (040700-189987672):1)
at com.android.volley.toolbox.BasicNetwork.performRequest(:com.google.android.gms#12521024#12.5.21 (040700-189987672):11)
at nmc.performRequest(:com.google.android.gms#12521024#12.5.21 (040700-189987672):8)
at com.android.volley.NetworkDispatcher.a(:com.google.android.gms#12521024#12.5.21 (040700-189987672):7)
at com.android.volley.NetworkDispatcher.run(:com.google.android.gms#12521024#12.5.21 (040700-189987672):2)
Caused by: mpw: 29503:
at mvf.a(:com.google.android.gms#12521024#12.5.21 (040700-189987672):3)
at aejp.b(:com.google.android.gms#12521024#12.5.21 (040700-189987672):4)
at aema.a(:com.google.android.gms#12521024#12.5.21 (040700-189987672):4)
at nof.a(:com.google.android.gms#12521024#12.5.21 (040700-189987672):6)
at noj.run(:com.google.android.gms#12521024#12.5.21 (040700-189987672):44)
at axja.run(:com.google.android.gms#12521024#12.5.21 (040700-189987672):2)
at nsg.run(:com.google.android.gms#12521024#12.5.21 (040700-189987672):27)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at nya.run(Unknown Source:7)
at java.lang.Thread.run(Thread.java:764)
It's so wired, because of task invocation on ThreadExecutor. To get correct log of your issues, you should wrap action, which you submit in background with your tools (executor Service, Rx, or even AsyncTask) with try-cath block.
Getting this error in sample app.
java.net.ProtocolException: Expected HTTP 101 response but was '401
Not Authorized'
Using this code snippet to transalate.
TranslateOptions translateOptions = new TranslateOptions.Builder()
.addText(params[0])
.source(Language.ENGLISH)
.target(selectedTargetLanguage)
.build();
TranslationResult translationResult = translationService
.translate(translateOptions)
.execute();
Once it executes the application crashes and I see this error in logs.
D/OkHttp: --> POST https://gateway.watsonplatform.net/language-translator/api/v2/translate/v2/translate http/1.1 (46-byte body)
D/OkHttp: <-- 401 Not Authorized https://gateway.watsonplatform.net/language-translator/api/v2/translate/v2/translate (413ms, unknown-length body)
POST https://gateway.watsonplatform.net/language-translator/api/v2/translate/v2/translate, status: 401, error: Not Authorized
--------- beginning of crash
E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #3
Process: com.gobiggi.watsontutorial, PID: 10136
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:325)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
Caused by:
com.ibm.watson.developer_cloud.service.exception.UnauthorizedException: Unauthorized: Access is denied due to invalid credentials. Tip: Did you set the Endpoint?
at com.ibm.watson.developer_cloud.service.WatsonService.processServiceCall(WatsonService.java:410)
at com.ibm.watson.developer_cloud.service.WatsonService$1.execute(WatsonService.java:174)
at com.gobiggi.watsontutorial.MainActivity$TranslationTask.doInBackground(MainActivity.java:328)
at com.gobiggi.watsontutorial.MainActivity$TranslationTask.doInBackground(MainActivity.java:321)
at android.os.AsyncTask$2.call(AsyncTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
i don't know too much about how watson sdk works but just by looking at the error i see:
com.ibm.watson.developer_cloud.service.exception.UnauthorizedException:
Unauthorized: Access is denied due to invalid credentials. Tip: Did
you set the Endpoint?
Is saying the credentials presented are not valid. You should start by looking at that.
I am facing the following exception when i try to call method on server, can any one tell me what is the problem ?
stacktrace
java.io.FileNotFoundException: https://services.q84sale.com/live/index.php/V1/Users/register
at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:186)
com.android.okhttp.internal.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:246)
com.forsale.forsale.controller.manager.ForSaleNetworkManager.execute(ForSaleNetworkManager.java:116)
com.forsale.forsale.controller.manager.ForSaleServerManager$18.doInBackground(ForSaleServerManager.java:1423)
com.forsale.forsale.controller.manager.ForSaleServerManager$18.doInBackground(ForSaleServerManager.java:1399)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:848)
Too little information for right answer. Probably:
You specified an object with in your query that doesn't exist on server
You are using wrong method (GET, PUT) instead of POST
Server has some errors in its code
Add:
I noticed you are using .getInputStream() after receiving response code above 399. Check .getResponseCode() and then use .getErrorStream() instead
My Interface is like this
#Headers("Content-Type: application/json")
#GET("/api/session/{id}")
void getSession(
#Path("id") String id, Callback<JsonObject> callback
);
But I keep getting, No retrofit annotation found. When searched why this error, the most common answer was that the request was expecting #Body. But I don't want to give a body its part of my url.
Exception that I am getting
java.lang.IllegalArgumentException: AuthApi.getSession: No Retrofit annotation found.
(Parameter#1)
at retrofit.RestMethodInfo.methodError(RestMethodInfo.java:123)
at retrofit.RestMethodInfo.parameterError(RestMethodInfo.java:127)
at retrofit.RestMethodInfo.parseParameters(RestMethodInfo.java:450)
at retrofit.RestMethodInfo.init(RestMethodInfo.java:134)
at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:294)
at retrofit.RestAdapter$RestHandler.access$100(RestAdapter.java:220)
at retrofit.RestAdapter$RestHandler$2.obtainResponse(RestAdapter.java:278)
at retrofit.CallbackRunnable.run(CallbackRunnable.java:42)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at retrofit.Platform$Android$2$1.run(Platform.java:142)
at java.lang.Thread.run(Thread.java:841)
END ERROR
I had the same issue with Retrofit using SimpleXML Converter.
The problem was an import, I had:
import org.simpleframework.xml.Path;
instead of:
import retrofit.http.Path;