Socket error while trying to save attachment to cb lite

Hello,

Recently I have been seeing errors while trying to create attachments in cb-lite 1.4. Below is the HTTP request i am doing.

http://localhost:5984/myDatabase/docId/attachmentName.jpg?rev=revId
Body: Image Binary data
Content-Type: image/jpeg

A PUT with the above request, return a err_empty_response. When I checked the device logs I found the below

01-16 12:58:36.496  3866  3866 D SystemWebChromeClient: file:///android_asset/www/build/main.js: Line 1441 : [object Object]
01-16 12:58:36.497  3866  3866 I chromium: [INFO:CONSOLE(1441)] "[object Object]", source: file:///android_asset/www/build/main.js (1441)
01-16 12:58:36.500  3866  4117 V Database: PUT _id=b1c7d993-bde2-4daf-bdc5-6d07eb8645c1, _rev=1-345f334481ad46a139d319804c0155ef (allowConflict=false)
01-16 12:58:36.504  3866  4117 V Database: Acme.Utils.ThreadPool(0)-PooledThread: Acme.Serve.Serve$ServeConnection@af0fb28 Begin transaction (level 0)
01-16 12:58:36.509  3866  4117 V Database: Acme.Utils.ThreadPool(0)-PooledThread: Acme.Serve.Serve$ServeConnection@af0fb28 Committing transaction (level 0)
01-16 12:58:36.523  3866  4117 V CBLite  : ---> Added: {b1c7d993-bde2-4daf-bdc5-6d07eb8645c1 #2-79cd01f371ce7f071f3c185ab3d0d565 @4} as seq 4
01-16 12:58:36.523  3866  4117 V Listener: RouterCallbackBlock.onResponseReady() START
01-16 12:58:36.523  3866  4117 V Listener: RouterCallbackBlock.onResponseReady() END
01-16 12:58:36.523  3866  4117 V Listener: CountDownLatch.await() START
01-16 12:58:36.523  3866  4117 V Listener: CountDownLatch.await() END

> 01-16 12:58:36.524 3866 4117 W System.err: [Wed Jan 16 12:58:36 CST 2019] TJWS: IO error: java.net.SocketException: sendto failed: EBADF (Bad file descriptor) in processing a request /inspections_db/b1c7d993-bde2-4daf-bdc5-6d07eb8645c1/1547665085801.jpg from /127.0.0.1:5984 / java.net.Socket

Interesting to note is that the attachment gets saved perfectly fine, but the PUT request fails. Any idea why this exception would be occurring ?

Environment
Android 6.0
CB-LITE 1.4
App Type: Hybrid
Plugin: GitHub - sumeet-singh04/Couchbase-Lite-PhoneGap-Plugin: Plugin to install Couchbase Lite in your PhoneGap app on Android

this looks like it is throwing error from Android. Does not look like throwing from cb lite. Is it peer 2 peer? Just wondering whether you have closed the socket connection on the receiving part of replication.

It seems to be a cb lite problem, since the java exception is point to the database we have on there

/inspections_db/b1c7d993-bde2-4daf-bdc5-6d07eb8645c1/1547665085801.jpg from /127.0.0.1:5984 / java.net.Socket
CB-Lite REST API does run by default on port 5984, and its clearly visible in the log.

I am using a Cordova plugin inside my Hybrid Mobile App without replication, may be the cordova plugin is doing something behind the scene.

So it seems like the IO error is being ignored, I looked into the source code and i think the IO error generated while closing the Blob file is being ignored

public boolean storeBlob(byte[] data, BlobKey outKey) {
        BlobKey newKey = keyForBlob(data);
        outKey.setBytes(newKey.getBytes());
        String path = getRawPathForKey(outKey);
        File file = new File(path);
        if (file.canRead()) {
            return true;
        }

        if (encryptionKey != null) {
            try {
                data = encryptionKey.encryptData(data);
            } catch (SymmetricKeyException e) {
                Log.w(Log.TAG_DATABASE, "BlobStore: Failed to encode data for " + path, e);
                return false;
            }
        }

        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(file);
            fos.write(data);
        } catch (FileNotFoundException e) {
            Log.e(Log.TAG_DATABASE, "BlobStore: Error opening file for output", e);
            return false;
        } catch (IOException ioe) {
            Log.e(Log.TAG_DATABASE, "BlobStore: Error writing to file", ioe);
            return false;
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    // ignore
            }
        }
    }
    return true;
}

catch (IOException e) {
// ignore
}

So is it fine to ignore the IO exception ?

I don’t think that’s related. You’re getting an exception from Couchbase Lite’s REST API server, not from the blob code. A failure to save a blob wouldn’t cause an error writing to the HTTP stream.

Yes, you are right, I later noticed the exception is occurring in TJWS. Anyway, is there a recommended way to handle this or something I should be doing differently to handle this ?

Maybe it’s an issue in TJWS? But I’m no Android expert; maybe @blake.meike can help…

My apologies for not getting on this earlier! So sorry!

I don’t have enough information to debug this. Can you supply a stacktrace for the error?

CountDownLatches make me nervous. Is that latch stalling the UI thread?