mirror of
				https://github.com/owncloud/android-library.git
				synced 2025-10-31 02:17:41 +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