Skip to content

Commit e80fa8d

Browse files
committed
MOBILE-3270 core: Revert some changes and improve error handling
1 parent 9057b62 commit e80fa8d

File tree

4 files changed

+17
-173
lines changed

4 files changed

+17
-173
lines changed

src/core/fileuploader/providers/helper.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import { Camera, CameraOptions } from '@ionic-native/camera';
1919
import { TranslateService } from '@ngx-translate/core';
2020
import { CoreAppProvider } from '@providers/app';
2121
import { CoreFileProvider, CoreFileProgressEvent } from '@providers/file';
22-
import { CoreFileHelperProvider } from '@providers/file-helper';
2322
import { CoreLoggerProvider } from '@providers/logger';
2423
import { CoreDomUtilsProvider } from '@providers/utils/dom';
2524
import { CoreTextUtilsProvider } from '@providers/utils/text';
@@ -48,8 +47,7 @@ export class CoreFileUploaderHelperProvider {
4847
protected actionSheetCtrl: ActionSheetController,
4948
protected uploaderDelegate: CoreFileUploaderDelegate,
5049
protected camera: Camera,
51-
protected platform: Platform,
52-
protected fileHelper: CoreFileHelperProvider) {
50+
protected platform: Platform) {
5351
this.logger = logger.getInstance('CoreFileUploaderProvider');
5452
}
5553

@@ -108,7 +106,7 @@ export class CoreFileUploaderHelperProvider {
108106
const filePath = this.textUtils.concatenatePaths(CoreFileProvider.TMPFOLDER, newName);
109107

110108
// Write the data into the file.
111-
return this.fileHelper.writeFileDataInFile(file, filePath, (progress: CoreFileProgressEvent) => {
109+
return this.fileProvider.writeFileDataInFile(file, filePath, (progress: CoreFileProgressEvent) => {
112110
this.showProgressModal(modal, 'core.fileuploader.readingfileperc', progress);
113111
});
114112
}).catch((error) => {
@@ -193,9 +191,7 @@ export class CoreFileUploaderHelperProvider {
193191
}
194192
});
195193

196-
this.domUtils.showErrorModal(errorMessage);
197-
198-
return Promise.reject(null);
194+
return Promise.reject(errorMessage);
199195
}
200196

201197
/**
@@ -649,7 +645,7 @@ export class CoreFileUploaderHelperProvider {
649645
this.fileProvider.removeExternalFile(path);
650646
}
651647

652-
return Promise.reject(null);
648+
return Promise.reject(this.domUtils.createCanceledError());
653649
});
654650
};
655651

src/providers/file-helper.ts

Lines changed: 2 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,13 @@
1515
import { Injectable } from '@angular/core';
1616
import { TranslateService } from '@ngx-translate/core';
1717
import { CoreAppProvider } from './app';
18-
import { CoreConfigProvider } from './config';
19-
import { CoreFileProvider, CoreFileProgressFunction } from './file';
18+
import { CoreFileProvider } from './file';
2019
import { CoreFilepoolProvider } from './filepool';
2120
import { CoreSitesProvider } from './sites';
2221
import { CoreWSProvider } from './ws';
23-
import { CoreDomUtilsProvider } from './utils/dom';
2422
import { CoreUrlUtils } from './utils/url';
2523
import { CoreUtilsProvider } from './utils/utils';
2624
import { CoreConstants } from '@core/constants';
27-
import { FileEntry } from '@ionic-native/file';
2825
import { makeSingleton } from '@singletons/core.singletons';
2926

3027
/**
@@ -33,23 +30,13 @@ import { makeSingleton } from '@singletons/core.singletons';
3330
@Injectable()
3431
export class CoreFileHelperProvider {
3532

36-
// Variables for reading files in chunks.
37-
protected MAX_CHUNK_SIZE_NAME = 'file_max_chunk_size';
38-
protected READ_CHUNK_ATTEMPT_NAME = 'file_read_chunk_attempt';
39-
protected maxChunkSize = -1;
40-
4133
constructor(protected fileProvider: CoreFileProvider,
4234
protected filepoolProvider: CoreFilepoolProvider,
4335
protected sitesProvider: CoreSitesProvider,
4436
protected appProvider: CoreAppProvider,
4537
protected translate: TranslateService,
4638
protected utils: CoreUtilsProvider,
47-
protected wsProvider: CoreWSProvider,
48-
protected configProvider: CoreConfigProvider,
49-
protected domUtils: CoreDomUtilsProvider) {
50-
51-
this.initMaxChunkSize();
52-
}
39+
protected wsProvider: CoreWSProvider) { }
5340

5441
/**
5542
* Convenience function to open a file, downloading it if needed.
@@ -258,34 +245,6 @@ export class CoreFileHelperProvider {
258245
return file.timemodified || 0;
259246
}
260247

261-
/**
262-
* Initialize the max chunk size.
263-
*
264-
* @return Promise resolved when done.
265-
*/
266-
protected async initMaxChunkSize(): Promise<void> {
267-
const sizes = await Promise.all([
268-
await this.configProvider.get(this.READ_CHUNK_ATTEMPT_NAME, -1), // Check if there is any attempt pending.
269-
await this.configProvider.get(this.MAX_CHUNK_SIZE_NAME, -1), // Retrieve current max chunk size from DB.
270-
]);
271-
272-
const attemptSize = sizes[0];
273-
const maxChunkSize = sizes[1];
274-
275-
if (attemptSize != -1 && (maxChunkSize == -1 || attemptSize < maxChunkSize)) {
276-
// Store the attempt's size as the max size.
277-
this.storeMaxChunkSize(attemptSize);
278-
} else {
279-
// No attempt or the max size is already lower. Keep current max size.
280-
this.maxChunkSize = maxChunkSize;
281-
}
282-
283-
if (attemptSize != -1) {
284-
// Clean pending attempt.
285-
await this.configProvider.delete(this.READ_CHUNK_ATTEMPT_NAME);
286-
}
287-
}
288-
289248
/**
290249
* Check if a state is downloaded or outdated.
291250
*
@@ -380,99 +339,6 @@ export class CoreFileHelperProvider {
380339

381340
throw new Error('Couldn\'t determine file size: ' + file.fileurl);
382341
}
383-
384-
/**
385-
* Save max chunk size.
386-
*
387-
* @param size Size to store.
388-
* @return Promise resolved when done.
389-
*/
390-
protected async storeMaxChunkSize(size: number): Promise<void> {
391-
this.maxChunkSize = size;
392-
393-
await this.configProvider.set(this.MAX_CHUNK_SIZE_NAME, size);
394-
}
395-
396-
/**
397-
* Write some file data into a filesystem file.
398-
* It's done in chunks to prevent crashing the app for big files.
399-
*
400-
* @param file The data to write.
401-
* @param path Path where to store the data.
402-
* @param onProgress Function to call on progress.
403-
* @param offset Offset where to start reading from.
404-
* @param append Whether to append the data to the end of the file.
405-
* @return Promise resolved when done.
406-
*/
407-
async writeFileDataInFile(file: Blob, path: string, onProgress?: CoreFileProgressFunction, offset: number = 0,
408-
append?: boolean): Promise<FileEntry> {
409-
410-
offset = offset || 0;
411-
412-
// Get the chunk to read and write.
413-
const readWholeFile = offset === 0 && CoreFileProvider.CHUNK_SIZE >= file.size;
414-
const chunk = readWholeFile ? file : file.slice(offset, Math.min(offset + CoreFileProvider.CHUNK_SIZE, file.size));
415-
416-
try {
417-
const fileEntry = await this.fileProvider.writeFileDataInFileChunk(chunk, path, append);
418-
419-
offset += CoreFileProvider.CHUNK_SIZE;
420-
421-
onProgress && onProgress({
422-
lengthComputable: true,
423-
loaded: offset,
424-
total: file.size
425-
});
426-
427-
if (offset >= file.size) {
428-
// Done, stop.
429-
return fileEntry;
430-
}
431-
432-
// Read the next chunk.
433-
return this.writeFileDataInFile(file, path, onProgress, offset, true);
434-
} catch (error) {
435-
if (readWholeFile || !error || error.name != 'NotReadableError') {
436-
return Promise.reject(error);
437-
}
438-
439-
// Permission error when reading file in chunks. This usually happens with Google Drive files.
440-
// Try to read the whole file at once.
441-
return this.writeBigFileDataInFile(file, path, onProgress);
442-
}
443-
}
444-
445-
/**
446-
* Writes a big file data into a filesystem file without using chunks.
447-
* The app can crash when doing this with big files, so this function will try to control the max size that works
448-
* and warn the user if he's trying to upload a file that is too big.
449-
*
450-
* @param file The data to write.
451-
* @param path Path where to store the data.
452-
* @param onProgress Function to call on progress.
453-
* @return Promise resolved with the file.
454-
*/
455-
protected async writeBigFileDataInFile(file: Blob, path: string, onProgress?: CoreFileProgressFunction): Promise<FileEntry> {
456-
if (this.maxChunkSize != -1 && file.size >= this.maxChunkSize) {
457-
// The file size is bigger than the max allowed size. Ask the user to confirm.
458-
await this.domUtils.showConfirm(this.translate.instant('core.confirmreadfiletoobig'));
459-
}
460-
461-
// Store the "attempt".
462-
await this.configProvider.set(this.READ_CHUNK_ATTEMPT_NAME, file.size);
463-
464-
// Write the whole file.
465-
const fileEntry = await this.fileProvider.writeFileDataInFileChunk(file, path, false);
466-
467-
// Success, remove the attempt and increase the max chunk size if needed.
468-
await this.configProvider.delete(this.READ_CHUNK_ATTEMPT_NAME);
469-
470-
if (file.size > this.maxChunkSize) {
471-
await this.storeMaxChunkSize(file.size + 1);
472-
}
473-
474-
return fileEntry;
475-
}
476342
}
477343

478344
export class CoreFileHelper extends makeSingleton(CoreFileHelperProvider) {}

src/providers/file.ts

Lines changed: 10 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export class CoreFileProvider {
6565
static SITESFOLDER = 'sites';
6666
static TMPFOLDER = 'tmp';
6767

68-
static CHUNK_SIZE = 10485760; // 10 MB.
68+
static CHUNK_SIZE = 1048576; // 1 MB. Same chunk size as Ionic Native.
6969

7070
protected logger;
7171
protected initialized = false;
@@ -639,26 +639,25 @@ export class CoreFileProvider {
639639
/**
640640
* Write some file data into a filesystem file.
641641
* It's done in chunks to prevent crashing the app for big files.
642+
* Please notice Ionic Native writeFile function already splits by chunks, but it doesn't have an onProgress function.
642643
*
643644
* @param file The data to write.
644645
* @param path Path where to store the data.
645646
* @param onProgress Function to call on progress.
646647
* @param offset Offset where to start reading from.
647648
* @param append Whether to append the data to the end of the file.
648649
* @return Promise resolved when done.
649-
* @deprecated since 3.8.3. Please use CoreFileHelperProvider.writeFileDataInFile instead.
650650
*/
651651
async writeFileDataInFile(file: Blob, path: string, onProgress?: CoreFileProgressFunction, offset: number = 0,
652652
append?: boolean): Promise<FileEntry> {
653653

654654
offset = offset || 0;
655655

656-
// Get the chunk to read and write.
657-
const readWholeFile = offset === 0 && CoreFileProvider.CHUNK_SIZE >= file.size;
658-
const chunk = readWholeFile ? file : file.slice(offset, Math.min(offset + CoreFileProvider.CHUNK_SIZE, file.size));
659-
660656
try {
661-
const fileEntry = await this.writeFileDataInFileChunk(chunk, path, append);
657+
// Get the chunk to write.
658+
const chunk = file.slice(offset, Math.min(offset + CoreFileProvider.CHUNK_SIZE, file.size));
659+
660+
const fileEntry = await this.writeFile(path, chunk, append);
662661

663662
offset += CoreFileProvider.CHUNK_SIZE;
664663

@@ -676,32 +675,15 @@ export class CoreFileProvider {
676675
// Read the next chunk.
677676
return this.writeFileDataInFile(file, path, onProgress, offset, true);
678677
} catch (error) {
679-
if (readWholeFile || !error || error.name != 'NotReadableError') {
680-
return Promise.reject(error);
678+
if (error && error.target && error.target.error) {
679+
// Error returned by the writer, get the "real" error.
680+
error = error.target.error;
681681
}
682682

683-
// Permission error when reading file in chunks. This usually happens with Google Drive files.
684-
// Try to read the whole file at once.
685-
return this.writeFileDataInFileChunk(file, path, false);
683+
throw error;
686684
}
687685
}
688686

689-
/**
690-
* Write a chunk of data into a file.
691-
*
692-
* @param chunkData The chunk of data.
693-
* @param path Path where to store the data.
694-
* @param append Whether to append the data to the end of the file.
695-
* @return Promise resolved when done.
696-
*/
697-
writeFileDataInFileChunk(chunkData: Blob, path: string, append?: boolean): Promise<FileEntry> {
698-
// Read the chunk data.
699-
return this.readFileData(chunkData, CoreFileProvider.FORMATARRAYBUFFER).then((fileData) => {
700-
// Write the data in the file.
701-
return this.writeFile(path, fileData, append);
702-
});
703-
}
704-
705687
/**
706688
* Gets a file that might be outside the app's folder.
707689
*

src/providers/ws.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -901,7 +901,7 @@ export class CoreWSProvider {
901901

902902
return transfer.upload(filePath, uploadUrl, options, true).then((success) => {
903903
const data = this.textUtils.parseJSON(success.response, null,
904-
this.logger.error.bind(this.logger, 'Error parsing response from upload'));
904+
this.logger.error.bind(this.logger, 'Error parsing response from upload', success.response));
905905
if (data === null) {
906906
return Promise.reject(this.translate.instant('core.errorinvalidresponse'));
907907
}

0 commit comments

Comments
 (0)