mirror of
https://github.com/owncloud/android-library.git
synced 2025-06-08 00:16:09 +00:00
Improved detection of exceptions in uplaods due to local errors
This commit is contained in:
parent
78b9aa6247
commit
0bfc385707
@ -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");
|
||||
@ -119,15 +122,20 @@ public class ChunkFromFileChannelRequestEntity implements RequestEntity, Progres
|
||||
public void writeRequest(final OutputStream out) throws IOException {
|
||||
int readCount = 0;
|
||||
Iterator<OnDatatransferProgressListener> it = null;
|
||||
|
||||
try {
|
||||
|
||||
try {
|
||||
mChannel.position(mOffset);
|
||||
long size = mFile.length();
|
||||
if (size == 0) size = -1;
|
||||
long maxCount = Math.min(mOffset + mChunkSize, mChannel.size());
|
||||
while (mChannel.position() < maxCount) {
|
||||
readCount = mChannel.read(mBuffer);
|
||||
out.write(mBuffer.array(), 0, readCount);
|
||||
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;
|
||||
@ -139,12 +147,21 @@ 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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -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) {
|
||||
out.write(tmp.array(), 0, readResult);
|
||||
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) {
|
||||
@ -124,14 +127,39 @@ 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 {
|
||||
channel.close();
|
||||
raf.close();
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user