My server response looks like this:
HTTP/1.1 500 Internal server error
Date: Mon, 24 Oct 2022 10:37:05 GMT
Connection: keep-alive
I have no content in response, except headers.
I call chain.proceed(chain.request()).body()!!.string() inside my Interceptor and after some time of waiting .string() method throws SocketTimeoutException (However I expected to get an empty string there):
java.net.SocketTimeoutException: timeout
W/System.err: at okio.SocketAsyncTimeout.newTimeoutException(JvmOkio.kt:146)
W/System.err: at okio.AsyncTimeout.access$newTimeoutException(AsyncTimeout.kt:158)
W/System.err: at okio.AsyncTimeout$source$1.read(AsyncTimeout.kt:337)
W/System.err: at okio.RealBufferedSource.read(RealBufferedSource.kt:189)
W/System.err: at okhttp3.internal.http1.Http1ExchangeCodec$AbstractSource.read(Http1ExchangeCodec.java:389)
W/System.err: at okhttp3.internal.http1.Http1ExchangeCodec$UnknownLengthSource.read(Http1ExchangeCodec.java:529)
W/System.err: at okhttp3.internal.connection.Exchange$ResponseBodySource.read(Exchange.java:286)
W/System.err: at okio.RealBufferedSource.read(RealBufferedSource.kt:189)
W/System.err: at com.chuckerteam.chucker.internal.support.TeeSource.read(TeeSource.kt:24)
W/System.err: at okio.RealBufferedSource.select(RealBufferedSource.kt:229)
W/System.err: at okhttp3.internal.Util.bomAwareCharset(Util.java:467)
W/System.err: at okhttp3.ResponseBody.string(ResponseBody.java:181)
W/System.err: at ServerErrorConverter.getResponseContent(ServerErrorConverter.kt:156)
I can't find the reason for that behaviour and/or how to fix it. The only what I've found was that if my response contains Content-Length: 0 header, everything works OK.
Related
I have a simple POST request for registering a location in our backend which should respond a string with the locationId and an unique registration code which gets shown for other stuff. In Postman the request looks like: 120:B6IRDAEDZ82BCDMP9QUK which is fine.
So, I've built a retrofit request which simply does the same:
#POST("remote_montage/set_credentials/{locationId}")
suspend fun getRegistrationQrCode(
#Path("locationId") locationId: Int
): Response<String>
Now, if I call it in my repository, it throws me this Error
com.google.gson.stream.MalformedJsonException: Expected value at line 1 column 4 path $
W/System.err: at com.google.gson.stream.JsonReader.syntaxError(JsonReader.java:1568)
W/System.err: at com.google.gson.stream.JsonReader.doPeek(JsonReader.java:590)
W/System.err: at com.google.gson.stream.JsonReader.peek(JsonReader.java:425)
W/System.err: at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:41)
W/System.err: at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:27)
W/System.err: at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:243)
W/System.err: at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:153)
W/System.err: at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:519)
W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
W/System.err: at java.lang.Thread.run(Thread.java:923)
I have no Idea what this means. What Columns? What value? What Line?
The GsonConverterFactory you are providing to retrofit is looking at the response and finding that it is invalid JSON.
You should use ScalarsConverterFactory which is designed to convert string responses
implementation 'com.squareup.retrofit2:converter-scalars:2.1.0'
and add it to your retrofit builder
.addConverterFactory(ScalarsConverterFactory.create())
I am trying to upload an image captured by camera to FTP server, I am using FTPClient object, and it is working successfully when running the Java code on computer, but it fails when running the code on an android device.
I have checked the INTERNET permission, also internet connection is stable, also the other internet related functions are working correctly, only this ftp client is not working.
Here is the code:
FTPClient ftpClient = new FTPClient();
ftpClient.connect("ftp.mywebsite.com",21);
Please note that mywebsite is just a place holder.
It is throwing the following FTPConnectionClosedException exception
W/System.err: org.apache.commons.net.ftp.FTPConnectionClosedException: Connection closed without indication.
W/System.err: at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:324)
W/System.err: at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:300)
W/System.err: at org.apache.commons.net.ftp.FTP._connectAction_(FTP.java:425)
W/System.err: at org.apache.commons.net.ftp.FTPClient._connectAction_(FTPClient.java:962)
W/System.err: at org.apache.commons.net.ftp.FTPClient._connectAction_(FTPClient.java:950)
W/System.err: at org.apache.commons.net.SocketClient._connect(SocketClient.java:244)
W/System.err: at org.apache.commons.net.SocketClient.connect(SocketClient.java:202)
W/System.err: at com.basma.basma_rider.Helper$3.doInBackground(Helper.java:367)
W/System.err: at com.basma.basma_rider.Helper$3.doInBackground(Helper.java:342)
W/System.err: at android.os.AsyncTask$2.call(AsyncTask.java:288)
W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:237)
W/System.err: at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
W/System.err: at java.lang.Thread.run(Thread.java:841)
After getting facebook access token, i use it for login in my own web server. However in the first time, there is warning in the log file, and i can not load data from my server, but when i open app from second times, it load normally.
Below is warning log:
W/System.err: com.google.gson.JsonSyntaxException:
java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING
at line 1 column 1 path $ W/System.err: at
com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:224)
W/System.err: at
retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:39)
W/System.err: at
retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:27)
W/System.err: at
retrofit2.ServiceMethod.toResponse(ServiceMethod.java:122)
W/System.err: at
retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:217) W/System.err:
at retrofit2.OkHttpCall.execute(OkHttpCall.java:180) W/System.err:
at
retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:42) W/System.err: at
io.reactivex.Observable.subscribe(Observable.java:12084) W/System.err:
at
retrofit2.adapter.rxjava2.BodyObservable.subscribeActual(BodyObservable.java:34)
W/System.err: at
io.reactivex.Observable.subscribe(Observable.java:12084) W/System.err:
at
io.reactivex.internal.operators.observable.ObservableSingleSingle.subscribeActual(ObservableSingleSingle.java:35)
W/System.err: at io.reactivex.Single.subscribe(Single.java:3433)
W/System.err: at
io.reactivex.internal.operators.single.SingleDoOnSuccess.subscribeActual(SingleDoOnSuccess.java:35)
W/System.err: at io.reactivex.Single.subscribe(Single.java:3433)
W/System.err: at
io.reactivex.internal.operators.single.SingleSubscribeOn$SubscribeOnObserver.run(SingleSubscribeOn.java:89)
W/System.err: at
io.reactivex.Scheduler$DisposeTask.run(Scheduler.java:579)
W/System.err: at
io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:66)
W/System.err: at
io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:57)
W/System.err: at
java.util.concurrent.FutureTask.run(FutureTask.java:266) W/System.err:
at
java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
W/System.err: at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
W/System.err: at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
W/System.err: at java.lang.Thread.run(Thread.java:764)
W/System.err: Caused by: java.lang.IllegalStateException: Expected
BEGIN_OBJECT but was STRING at line 1 column 1 path $ W/System.err:
at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:385)
W/System.err: at
com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:213)
What could be causing this?
That error tells you that there is an error when GSON tries to parse the JSON returned by the web service you're calling. In particular, GSON is expecting a JSON object, but it receives a string (see the first line of the error message).
If the error happens only the first time you call it and not the second it means that the web service returns 2 different answers, and GSON can correctly parse the second one, but not the first one.
In order to find out what's wrong, you should provide more details, like your data model and the 2 responses returned by the web service.
I am uploading .mp4 video using Retrofit 2.1.0 and OKHTTP 3.6.0. On some videos, I am having this exception. The timeout is set to 30 sec.
okhttp3.internal.http2.StreamResetException: stream was reset: FLOW_CONTROL_ERROR
W/System.err: at okhttp3.internal.http2.Http2Stream.checkOutNotClosed(Http2Stream.java:567)
W/System.err: at okhttp3.internal.http2.Http2Stream$FramingSink.emitFrame(Http2Stream.java:501)
W/System.err: at okhttp3.internal.http2.Http2Stream$FramingSink.write(Http2Stream.java:481)
W/System.err: at okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:171)
W/System.err: at okio.RealBufferedSink.write(RealBufferedSink.java:91)
I tried adding a retry policy (https://stackoverflow.com/a/22169775/2098493)
but the error persist when file being uploaded is larger than 1mb.
W/System.err: com.android.volley.NoConnectionError: javax.net.ssl.SSLException: Write error: ssl=0xafc3fe00: I/O error during system call, Connection reset by peer
W/System.err: at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:151)
W/System.err: at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:112)
W/System.err: Caused by: javax.net.ssl.SSLException: Write error: ssl=0xafc3fe00: I/O error during system call, Connection reset by peer
W/System.err: at com.android.org.conscrypt.NativeCrypto.SSL_write(Native Method)
W/System.err: at com.android.org.conscrypt.OpenSSLSocketImpl$SSLOutputStream.write(OpenSSLSocketImpl.java:765)
W/System.err: at com.android.okio.Okio$1.write(Okio.java:70)
W/System.err: at com.android.okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:116)
W/System.err: at com.android.okio.RealBufferedSink.write(RealBufferedSink.java:44)
W/System.err: at com.android.okhttp.internal.http.RetryableSink.writeToSocket(RetryableSink.java:77)
W/System.err: at com.android.okhttp.internal.http.HttpConnection.writeRequestBody(HttpConnection.java:240)
W/System.err: at com.android.okhttp.internal.http.HttpTransport.writeRequestBody(HttpTransport.java:77)
W/System.err: at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:622)
W/System.err: at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:388)
W/System.err: at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:332)
W/System.err: at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:500)
W/System.err: at com.android.okhttp.internal.http.DelegatingHttpsURLConnection.getResponseCode(DelegatingHttpsURLConnection.java:105)
W/System.err: at com.android.okhttp.internal.http.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:25)
W/System.err: at com.android.volley.toolbox.HurlStack.performRequest(HurlStack.java:110)
W/System.err: at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:96)
Thanks for your advice.
The solution was a combination of adding Volley Retry Policy and making sure back-end and server (nodejs/nginx) max uploaded file size are both set correctly.
//where RETRY_DEFAULT_TIMEOUT_MS = 5000, RETRY_DEFAULT_MAX_RETRIES = 3, RETRY_DEFAULT_BACKOFF_MULT = 2.0f
request.setRetryPolicy(new DefaultRetryPolicy(RETRY_DEFAULT_TIMEOUT_MS,
RETRY_DEFAULT_MAX_RETRIES,
RETRY_DEFAULT_BACKOFF_MULT));