Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0bfc3857 authored by David A. Velasco's avatar David A. Velasco
Browse files

Improved detection of exceptions in uplaods due to local errors

parent 78b9aa62
Loading
Loading
Loading
Loading
+25 −8
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
package com.owncloud.android.lib.common.network;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
@@ -58,7 +59,9 @@ public class ChunkFromFileChannelRequestEntity implements RequestEntity, Progres
    Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<OnDatatransferProgressListener>();
    private ByteBuffer mBuffer = ByteBuffer.allocate(4096);

    public ChunkFromFileChannelRequestEntity(final FileChannel channel, final String contentType, long chunkSize, final File file) {
    public ChunkFromFileChannelRequestEntity(
        final FileChannel channel, final String contentType, long chunkSize, final File file
    ) {
        super();
        if (channel == null) {
            throw new IllegalArgumentException("File may not be null");
@@ -127,7 +130,12 @@ public class ChunkFromFileChannelRequestEntity implements RequestEntity, Progres
            long maxCount = Math.min(mOffset + mChunkSize, mChannel.size());
            while (mChannel.position() < maxCount) {
                readCount = mChannel.read(mBuffer);
                try {
                    out.write(mBuffer.array(), 0, readCount);
                } catch (IOException io) {
                    // work-around try catch to filter exception in writing
                    throw new FileRequestEntity.WriteException(io);
                }
                mBuffer.clear();
                if (mTransferred < maxCount) {  // condition to avoid accumulate progress for repeated chunks
                    mTransferred += readCount;
@@ -141,10 +149,19 @@ public class ChunkFromFileChannelRequestEntity implements RequestEntity, Progres
            }

        } catch (IOException io) {
            Log_OC.e(TAG, io.getMessage());
            throw new RuntimeException("Ugly solution to workaround the default policy of retries when the server falls while uploading ; temporal fix; really", io);   
            // any read problem will be handled as if the file is not there
            if (io instanceof FileNotFoundException) {
                throw io;
            } else {
                FileNotFoundException fnf = new FileNotFoundException("Exception reading source file");
                fnf.initCause(io);
                throw fnf;
            }

        } catch (FileRequestEntity.WriteException we) {
            throw we.getWrapped();
        }
            
    }

}
 No newline at end of file
+38 −10
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
package com.owncloud.android.lib.common.network;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
@@ -100,12 +101,9 @@ public class FileRequestEntity implements RequestEntity, ProgressiveDataTransfer
    
    @Override
    public void writeRequest(final OutputStream out) throws IOException {
        //byte[] tmp = new byte[4096];
        ByteBuffer tmp = ByteBuffer.allocate(4096);
        int readResult = 0;
        
        // TODO(bprzybylski): each mem allocation can throw OutOfMemoryError we need to handle it
        //                    globally in some fashionable manner
        RandomAccessFile raf = new RandomAccessFile(mFile, "r");
        FileChannel channel = raf.getChannel();
        Iterator<OnDatatransferProgressListener> it = null;
@@ -114,7 +112,12 @@ public class FileRequestEntity implements RequestEntity, ProgressiveDataTransfer
        if (size == 0) size = -1;
        try {
            while ((readResult = channel.read(tmp)) >= 0) {
                try {
                    out.write(tmp.array(), 0, readResult);
                } catch (IOException io) {
                    // work-around try catch to filter exception in writing
                    throw new WriteException(io);
                }
                tmp.clear();
                transferred += readResult;
                synchronized (mDataTransferListeners) {
@@ -126,12 +129,37 @@ public class FileRequestEntity implements RequestEntity, ProgressiveDataTransfer
            }

        } catch (IOException io) {
            Log_OC.e("FileRequestException", io.getMessage());
            throw new RuntimeException("Ugly solution to workaround the default policy of retries when the server falls while uploading ; temporal fix; really", io);   
            // any read problem will be handled as if the file is not there
            if (io instanceof FileNotFoundException) {
                throw io;
            } else {
                FileNotFoundException fnf = new FileNotFoundException("Exception reading source file");
                fnf.initCause(io);
                throw fnf;
            }

        } catch (WriteException we) {
            throw we.getWrapped();

        } finally {
            try {
                channel.close();
                raf.close();
            } catch (IOException io) {
                // ignore failures closing source file
            }
        }
    }

    protected static class WriteException extends Exception {
        IOException mWrapped;

        WriteException(IOException wrapped) {
            mWrapped = wrapped;
        }

        public IOException getWrapped() {
            return mWrapped;
        }
    }

+4 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
package com.owncloud.android.lib.common.operations;

import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
@@ -260,6 +261,9 @@ public class RemoteOperationResult implements Serializable {
                mCode = ResultCode.SSL_ERROR;
            }

        } else if (e instanceof FileNotFoundException) {
            mCode = ResultCode.LOCAL_FILE_NOT_FOUND;

        } else {
            mCode = ResultCode.UNKNOWN_ERROR;
        }
+16 −0
Original line number Diff line number Diff line
@@ -32,9 +32,11 @@ import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;

import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.params.HttpMethodParams;

import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.network.FileRequestEntity;
@@ -87,8 +89,16 @@ public class UploadRemoteFileOperation extends RemoteOperation {
	@Override
	protected RemoteOperationResult run(OwnCloudClient client) {
		RemoteOperationResult result = null;
		DefaultHttpMethodRetryHandler oldRetryHandler =
			(DefaultHttpMethodRetryHandler) client.getParams().getParameter(HttpMethodParams.RETRY_HANDLER);

		try {
			// prevent that uploads are retried automatically by network library
			client.getParams().setParameter(
				HttpMethodParams.RETRY_HANDLER,
				new DefaultHttpMethodRetryHandler(0, false)
			);

			mPutMethod = new PutMethod(client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath));

			if (mCancellationRequested.get()) {
@@ -114,6 +124,12 @@ public class UploadRemoteFileOperation extends RemoteOperation {
			} else {
				result = new RemoteOperationResult(e);
			}
		} finally {
			// reset previous retry handler
			client.getParams().setParameter(
				HttpMethodParams.RETRY_HANDLER,
				oldRetryHandler
			);
		}
		return result;
	}