From ea49dd25e49c89c6fc07a10c9e1079574a04eedb Mon Sep 17 00:00:00 2001 From: Benjamin Vadon Date: Thu, 16 Apr 2026 07:18:02 +0200 Subject: [PATCH 1/8] refactor: Clean nullability --- app/src/main/java/com/infomaniak/drive/data/api/UploadTask.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/infomaniak/drive/data/api/UploadTask.kt b/app/src/main/java/com/infomaniak/drive/data/api/UploadTask.kt index 619977ce04..97bd064682 100644 --- a/app/src/main/java/com/infomaniak/drive/data/api/UploadTask.kt +++ b/app/src/main/java/com/infomaniak/drive/data/api/UploadTask.kt @@ -473,8 +473,8 @@ class UploadTask( ) return ApiRepository.startUploadSession(driveId, sessionBody, okHttpClient).also { - if (it.isSuccess()) it.data?.token?.let { uploadToken -> - uploadFile.updateUploadToken(uploadToken, it.data!!.uploadHost) + if (it.isSuccess()) it.data?.run { + uploadFile.updateUploadToken(token, uploadHost) } else { it.manageUploadErrors() } From 1b855d7ebcffffd0b110070b978f42d3adc0c4c2 Mon Sep 17 00:00:00 2001 From: Benjamin Vadon Date: Tue, 21 Apr 2026 15:42:39 +0200 Subject: [PATCH 2/8] feat: Add missing strings --- app/src/main/res/values-da/strings.xml | 3 +++ app/src/main/res/values-de/strings.xml | 3 +++ app/src/main/res/values-el/strings.xml | 3 +++ app/src/main/res/values-es/strings.xml | 3 +++ app/src/main/res/values-fi/strings.xml | 3 +++ app/src/main/res/values-fr/strings.xml | 3 +++ app/src/main/res/values-it/strings.xml | 3 +++ app/src/main/res/values-nb/strings.xml | 3 +++ app/src/main/res/values-nl/strings.xml | 3 +++ app/src/main/res/values-pl/strings.xml | 3 +++ app/src/main/res/values-pt/strings.xml | 3 +++ app/src/main/res/values-sv/strings.xml | 3 +++ app/src/main/res/values/strings.xml | 3 +++ 13 files changed, 39 insertions(+) diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index 98bc082859..fd6c6ea01f 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -269,6 +269,7 @@ Filen eller mappen findes allerede Filen er i øjeblikket åben af en anden bruger og kan ikke ændres Grænsen for filer i mappen nået + Der er opstået en fejl Ikke-gendannelseslink Fejl ved afslutning af deling Grænsen nået @@ -277,6 +278,7 @@ Flytningsfejl Netværksfejl Resultaterne kan være ufuldstændige + kDrive har ikke adgang til dit fotobibliotek Denne fil er blevet slettet permanent Forhåndsvisning af en fil i papirkurven er ikke mulig Ikke nok plads på din kDrive @@ -760,6 +762,7 @@ Upload suspenderet Venter på WiFi-netværk Utilstrækkelig tilgængelig RAM-hukommelse + Venter på Wi-Fi Nogle uploads er stadig i gang i kDrive. Åbn appen og hold enheden tilsluttet for at fremskynde upload. Upload suspenderet Yderligere tilladelser anmodet diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index c78834410b..b09973dbe3 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -269,6 +269,7 @@ Datei oder Ordner existiert bereits Diese Datei ist bereits von einem Benutzer geöffnet und kann nicht verändert werden Limit der Dateien im Ordner erreicht + Ein Fehler ist aufgetreten Link nicht wiederherstellbar Fehler beim Abbrechen der Freigabe Limit erreicht @@ -277,6 +278,7 @@ Fehler beim Verschieben Verbindungsproblem Die Ergebnisse können unvollständig sein + kDrive hat keinen Zugriff auf Ihre Fotobibliothek Diese Datei wurde endgültig gelöscht Die Vorschau auf eine Datei im Papierkorb ist nicht verfügbar Unzureichender Platz auf Ihrem kDrive @@ -760,6 +762,7 @@ Import ausgesetzt Warten auf WLAN Unzureichend verfügbarer RAM + Warten auf Wi-Fi Einige Uploads sind in kDrive noch im Gange. Öffnen Sie die App und lassen Sie das Gerät verbunden, um den Upload zu beschleunigen. Pause importieren Zusätzlich beantragte Genehmigungen diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 9f0530995e..f0c8e52f5f 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -269,6 +269,7 @@ Το αρχείο ή ο φάκελος υπάρχει ήδη Αυτό το αρχείο είναι αυτή τη στιγμή ανοιχτό από άλλον χρήστη και δεν μπορεί να τροποποιηθεί Έχει επιτευχθεί το όριο αρχείων στον φάκελο + Παρουσιάστηκε σφάλμα Σύνδεσμος μη ανακτήσιμος Σφάλμα κατά τη διακοπή της κοινής χρήσης Υπέρβαση ορίου @@ -277,6 +278,7 @@ Σφάλμα μετακίνησης Σφάλμα δικτύου Τα αποτελέσματα ενδέχεται να είναι ελλιπή + Το kDrive δεν έχει πρόσβαση στη βιβλιοθήκη φωτογραφιών σας Αυτό το αρχείο διαγράφηκε οριστικά Η προεπισκόπηση αρχείου στον κάδο δεν είναι δυνατή Δεν υπάρχει αρκετός χώρος στο kDrive σας @@ -760,6 +762,7 @@ Η μεταφόρτωση ανεστάλη Αναμονή για δίκτυο Wi-Fi Ανεπαρκής διαθέσιμη μνήμη RAM + Αναμονή για Wi-Fi Κάποιες μεταφορτώσεις εξακολουθούν να βρίσκονται σε εξέλιξη στο kDrive. Ανοίξτε την εφαρμογή και κρατήστε τη συσκευή συνδεδεμένη για να επιταχύνετε τη μεταφόρτωση. Η μεταφόρτωση ανεστάλη Ζητούνται πρόσθετες άδειες diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 93bf3b8da0..664b14fa2e 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -269,6 +269,7 @@ Archivo o carpeta ya existente El archivo está actualmente abierto por un usuario y no puede ser modificado Límite de archivos alcanzado en la carpeta + Se ha producido un error Enlace no recuperable Error al salir del uso compartido Límite alcanzado @@ -277,6 +278,7 @@ Error al moverlo Problema de conexión Los resultados pueden ser incompletos + kDrive no tiene acceso a tu biblioteca de fotos Se ha eliminado definitivamente este archivo La vista previa de un archivo en la papelera no está disponible Espacio insuficiente en tu kDrive @@ -760,6 +762,7 @@ Importación suspendida A la espera de red WiFi Insuficiente memoria RAM disponible + A la espera de Wi-Fi Algunas subidas siguen en curso en kDrive. Abre la aplicación y mantén el dispositivo conectado para acelerar la carga. Pausa de importación Permisos adicionales solicitados diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 3501e358b5..2434337b7b 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -269,6 +269,7 @@ Tiedosto tai kansio on jo olemassa Tämä tiedosto on tällä hetkellä toisen käyttäjän avaama eikä sitä voi muokata Kansion tiedostoraja saavutettu + Virhe on tapahtunut Linkkiä ei voi palauttaa Virhe jaon lopettamisessa Raja saavutettu @@ -277,6 +278,7 @@ Siirtovirhe Verkkovirhe Tulokset voivat olla puutteellisia + kDrivella ei ole pääsyä valokuvakirjastoosi Tämä tiedosto on poistettu pysyvästi Tiedoston esikatselu roskakorissa ei ole mahdollista Ei tarpeeksi tilaa kDrivessa @@ -760,6 +762,7 @@ Lähetys keskeytetty Odotetaan Wi-Fi-verkkoa Keskusmuisti ei riitä + Odotetaan Wi-Fiä Joitakin lähetyksiä on vielä käynnissä kDrivessä. Avaa sovellus ja pidä laite kytkettynä nopeuttaaksesi lähetystä. Lähetys keskeytetty Lisää käyttöoikeuksia pyydetty diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index d9a0240ca2..bfa24d6b25 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -269,6 +269,7 @@ Le fichier ou le dossier existe déjà Le fichier est actuellement ouvert par un utilisateur et ne peut être modifié Limite de fichiers dans le dossier atteinte + Une erreur est survenue Lien non récupérable Erreur lors de l’abandon du partage Limite atteinte @@ -277,6 +278,7 @@ Erreur lors du déplacement Problème de réseau Les résultats peuvent être incomplets + kDrive n’a pas accès à votre photothèque Ce fichier a été supprimé définitivement L’aperçu d’un fichier dans la corbeille n’est pas disponible Espace insuffisant sur votre kDrive @@ -760,6 +762,7 @@ Importation suspendue En attente de réseau Wi-Fi Mémoire vive disponible insuffisante + En attente de Wi-Fi Des importations sont toujours en cours dans kDrive. Ouvrez l’app et gardez l’appareil branché pour accélérer l’upload. Importation en pause Autorisations supplémentaires demandées diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index bb5fc393de..35af9d827d 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -269,6 +269,7 @@ Il file o la cartella esiste già Il file è attualmente aperto da un utente e non può essere modificato Limite file raggiunto nella cartella + Si è verificato un errore Link non recuperabile Errore durante l’abbandono della condivisione Limite raggiunto @@ -277,6 +278,7 @@ Errore durante lo spostamento Problema di connessione I risultati possono essere incompleti + kDrive non ha accesso alla vostra libreria di foto Il file è stato eliminato definitivamente L’anteprima di un file spostato nel cestino non è disponibile Spazio insufficiente sul kDrive @@ -760,6 +762,7 @@ Importazione sospesa In attesa di connessione alla rete Wi-Fi Insufficiente RAM disponibile + In attesa del Wi-Fi Alcuni caricamenti sono ancora in corso in kDrive. Aprite l’app e mantenete il dispositivo connesso per accelerare il caricamento. Pausa importazione Permessi aggiuntivi richiesti diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml index abd98fa00b..d6de0ab195 100644 --- a/app/src/main/res/values-nb/strings.xml +++ b/app/src/main/res/values-nb/strings.xml @@ -269,6 +269,7 @@ Fil eller mappe finnes allerede Denne filen er for øyeblikket åpen av en annen bruker og kan ikke endres Grensen for filer i mappen er nådd + En feil har oppstått Ikke-gjenopprettbar lenke Feil ved avslutning av deling Grensen er nådd @@ -277,6 +278,7 @@ Feil ved flytting Nettverksfeil Resultatene kan være ufullstendige + kDrive har ikke tilgang til ditt bild bibliotek Denne filen har blitt permanent slettet Forhåndsvisning av en fil i papirkurven er ikke mulig Ikke nok plass på din kDrive @@ -760,6 +762,7 @@ Opplasting suspendert Venter på Wi-Fi-nettverk Utilstrekkelig tilgjengelig RAM-minne + Venter på Wi-Fi Noen opplastinger er fortsatt i gang i kDrive. Åpne appen og hold enheten tilkoblet for å øke hastigheten på opplastingen. Opplasting suspendert Tilleggstillatelser forespurt diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 4af8b00e56..f2264951e3 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -269,6 +269,7 @@ Bestand of map bestaat al Dit bestand is momenteel geopend door een andere gebruiker en kan niet worden gewijzigd Limiet van bestanden in map bereikt + Er is een fout opgetreden Link niet herstelbaar Fout bij het stoppen van delen Limiet bereikt @@ -277,6 +278,7 @@ Verplaatsfout Netwerkfout Resultaten kunnen onvolledig zijn + kDrive heeft geen toegang tot je fotobibliotheek Dit bestand is permanent verwijderd Een voorbeeld van een bestand in de prullenbak is niet mogelijk Niet genoeg ruimte op uw kDrive @@ -760,6 +762,7 @@ Uploaden onderbroken Wachten op Wi-Fi netwerk Onvoldoende beschikbaar ram-geheugen + Wachten op Wi-Fi Sommige uploads zijn nog bezig in kDrive. Open de app en houd het apparaat verbonden om de upload te versnellen. Uploaden gepauzeerd Aanvullende toestemmingen aangevraagd diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 758770a528..7b4f5c2589 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -279,6 +279,7 @@ Plik lub folder już istnieje Ten plik jest obecnie otwarty przez innego użytkownika i nie może być zmodyfikowany Osiągnięto limit plików w folderze + Wystąpił błąd Nieodzyskiwalny link Błąd podczas zatrzymywania udostępniania Osiągnięto limit @@ -287,6 +288,7 @@ Błąd przenoszenia Błąd sieci Wyniki mogą być niekompletne + kDrive nie ma dostępu do biblioteki zdjęć Ten plik został trwale usunięty Podgląd pliku w koszu nie jest możliwy Brak miejsca na Twoim kDrive @@ -834,6 +836,7 @@ Przesyłanie wstrzymane Oczekiwanie na sieć Wi-Fi Niewystarczająca ilość dostępnej pamięci RAM + Oczekiwanie na Wi-Fi Niektóre przesyłania są nadal w toku w kDrive. Otwórz aplikację i utrzymuj urządzenie podłączone, aby przyspieszyć przesyłanie. Przesyłanie wstrzymane Zażądano dodatkowych uprawnień diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 04b6432fee..d4d48e28a8 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -269,6 +269,7 @@ O ficheiro ou pasta já existe Este ficheiro está atualmente aberto por outro utilizador e não pode ser modificado Limite de ficheiros na pasta atingido + Ocorreu um erro Link não recuperável Erro ao parar a partilha Limite excedido @@ -277,6 +278,7 @@ Erro ao mover Erro de rede Os resultados podem estar incompletos + O kDrive não tem acesso à sua biblioteca de fotos Este ficheiro foi eliminado permanentemente Não é possível pré-visualizar um ficheiro na reciclagem Espaço insuficiente no seu kDrive @@ -760,6 +762,7 @@ Carregamento suspenso À espera de rede Wi-Fi Memória RAM disponível insuficiente + À espera de Wi-Fi Alguns carregamentos estão ainda em curso no kDrive. Abra a app e mantenha o dispositivo ligado para acelerar o carregamento. Carregamento suspenso Permissões adicionais solicitadas diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index bfa4bf3e61..041f6ccac6 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -269,6 +269,7 @@ Filen eller mappen finns redan Denna fil är för närvarande öppen av en annan användare och kan inte ändras Gränsen för filer i mappen nådd + Ett fel har inträffat Ej återvinningsbar länk Fel vid avslutning av delning Gränsen nådd @@ -277,6 +278,7 @@ Flyttningsfel Nätverksfel Resultaten kan vara ofullständiga + kDrive har inte tillgång till ditt fotobibliotek Denna fil har permanent tagits bort Förhandsvisning av en fil i papperskorgen är inte möjlig Inte tillräckligt med utrymme på din kDrive @@ -760,6 +762,7 @@ Uppladdning pausad Väntar på Wi-Fi-nätverk Otillräckligt RAM-minne + Väntar på Wi-Fi Vissa uppladdningar pågår fortfarande i kDrive. Öppna appen och håll enheten ansluten för att påskynda uppladdningen. Uppladdning pausad Ytterligare behörigheter begärs diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f8d50fe9b4..12dd5fbe59 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -269,6 +269,7 @@ File or folder already exists This file is currently opened by another user and cannot be modified Limit of files in folder reached + An error has occurred Non-recoverable link Error when stopping sharing Limit exceeded @@ -277,6 +278,7 @@ Move error Network error Results may be incomplete + kDrive does not have access to your photo library This file has been permanently deleted Previewing a file in the trash is not possible Not enough space on your kDrive @@ -760,6 +762,7 @@ Upload suspended Waiting for WiFi network Insufficient available ram memory + Waiting for Wi-Fi Some uploads are still in progress in kDrive. Open the app and keep the device connected to speed up the upload. Upload suspended Additional permissions requested From 1752b171c47310601f6adda967f43f8ded58681b Mon Sep 17 00:00:00 2001 From: Benjamin Vadon Date: Tue, 21 Apr 2026 15:43:28 +0200 Subject: [PATCH 3/8] feat: Add drive error key in UploadFile model --- .../main/java/com/infomaniak/drive/data/api/UploadTask.kt | 1 + .../java/com/infomaniak/drive/data/models/UploadFile.kt | 6 ++++++ .../com/infomaniak/drive/data/sync/UploadMigration.kt | 8 ++++++-- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/infomaniak/drive/data/api/UploadTask.kt b/app/src/main/java/com/infomaniak/drive/data/api/UploadTask.kt index 97bd064682..a3423cce30 100644 --- a/app/src/main/java/com/infomaniak/drive/data/api/UploadTask.kt +++ b/app/src/main/java/com/infomaniak/drive/data/api/UploadTask.kt @@ -476,6 +476,7 @@ class UploadTask( if (it.isSuccess()) it.data?.run { uploadFile.updateUploadToken(token, uploadHost) } else { + uploadFile.updateUploadErrorKey(it.error?.code) it.manageUploadErrors() } }.data?.uploadHost diff --git a/app/src/main/java/com/infomaniak/drive/data/models/UploadFile.kt b/app/src/main/java/com/infomaniak/drive/data/models/UploadFile.kt index 7ce32a27cd..fa0d03da4a 100644 --- a/app/src/main/java/com/infomaniak/drive/data/models/UploadFile.kt +++ b/app/src/main/java/com/infomaniak/drive/data/models/UploadFile.kt @@ -32,6 +32,7 @@ import com.infomaniak.drive.data.api.ApiRepository import com.infomaniak.drive.data.api.UploadTask import com.infomaniak.drive.data.api.UploadTask.Companion.ConflictOption import com.infomaniak.drive.data.cache.DriveInfosController +import com.infomaniak.drive.data.models.up.DriveError import com.infomaniak.drive.data.sync.UploadMigration import com.infomaniak.drive.utils.AccountUtils import com.infomaniak.drive.utils.IOFile @@ -59,6 +60,7 @@ open class UploadFile( @PrimaryKey var uri: String = "", var deletedAt: Date? = null, var driveId: Int = -1, + private var _driveErrorKey: String? = null, var fileCreatedAt: Date? = null, var fileModifiedAt: Date = Date(), var fileName: String = "", @@ -138,6 +140,10 @@ open class UploadFile( } } + fun updateUploadErrorKey(driveErrorKey: String?) { + update { it._driveErrorKey = driveErrorKey } + } + fun deleteIfExists(keepFile: Boolean = false, customRealm: Realm? = null) { when (customRealm) { null -> getRealmInstance().use { deleteIfExistsInternal(keepFile = keepFile, it) } diff --git a/app/src/main/java/com/infomaniak/drive/data/sync/UploadMigration.kt b/app/src/main/java/com/infomaniak/drive/data/sync/UploadMigration.kt index 98d2679f6e..9d02c9a5ea 100644 --- a/app/src/main/java/com/infomaniak/drive/data/sync/UploadMigration.kt +++ b/app/src/main/java/com/infomaniak/drive/data/sync/UploadMigration.kt @@ -1,6 +1,6 @@ /* * Infomaniak kDrive - Android - * Copyright (C) 2022-2024 Infomaniak Network SA + * Copyright (C) 2022-2026 Infomaniak Network SA * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -116,9 +116,13 @@ class UploadMigration : RealmMigration { ?.addField("onlyWifiSyncMedia", Boolean::class.java, FieldAttribute.REQUIRED) } + if (oldVersion < 9L) {//stop use of oldVersionTemp as it is useless + schema.get(UploadFile::class.java.simpleName) + ?.addField("_driveErrorKey", String::class.java) + } } companion object { - const val DB_VERSION = 8L // Must be bumped when the schema changes + const val DB_VERSION = 9L // Must be bumped when the schema changes } } From 018fbfb7e6ed6260795a504008e0a55060688843 Mon Sep 17 00:00:00 2001 From: Benjamin Vadon Date: Tue, 21 Apr 2026 15:44:04 +0200 Subject: [PATCH 4/8] feat: Add DriveError type to manage right message --- app/build.gradle.kts | 1 + .../drive/data/models/UploadFile.kt | 3 + .../drive/data/models/up/DriveError.kt | 133 ++++++++++++++++++ 3 files changed, 137 insertions(+) create mode 100644 app/src/main/java/com/infomaniak/drive/data/models/up/DriveError.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index dbb1bb6c05..b0c45ed725 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -261,6 +261,7 @@ dependencies { androidTestRuntimeOnly(libs.android.test.runner) implementation(core.coil.gif) + implementation(kotlin("reflect")) // Compose implementation(libs.androidx.ui.android) diff --git a/app/src/main/java/com/infomaniak/drive/data/models/UploadFile.kt b/app/src/main/java/com/infomaniak/drive/data/models/UploadFile.kt index fa0d03da4a..ac663c7ab9 100644 --- a/app/src/main/java/com/infomaniak/drive/data/models/UploadFile.kt +++ b/app/src/main/java/com/infomaniak/drive/data/models/UploadFile.kt @@ -74,6 +74,9 @@ open class UploadFile( var userId: Int = -1, ) : RealmObject() { + val error: DriveError? + get() = DriveError.find(_driveErrorKey) + @delegate:Ignore val okHttpClient: OkHttpClient by lazy { runBlocking { AccountUtils.getHttpClient(userId = userId, timeout = 120) } } diff --git a/app/src/main/java/com/infomaniak/drive/data/models/up/DriveError.kt b/app/src/main/java/com/infomaniak/drive/data/models/up/DriveError.kt new file mode 100644 index 0000000000..46f7dfad40 --- /dev/null +++ b/app/src/main/java/com/infomaniak/drive/data/models/up/DriveError.kt @@ -0,0 +1,133 @@ +/* + * Infomaniak kDrive - Android + * Copyright (C) 2026 Infomaniak Network SA + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.infomaniak.drive.data.models.up + +import androidx.annotation.PluralsRes +import androidx.annotation.StringRes +import com.infomaniak.drive.R +import com.infomaniak.drive.data.models.up.DriveError.Server.ServerError +import com.infomaniak.drive.data.models.up.DriveError.Server.ServerPlurals +import splitties.init.appCtx +import kotlin.reflect.KClass + +sealed interface DriveError { + val key: String + + interface Plurals { + fun message(quantity: Int): String + } + + interface Message { + val message: String + } + + sealed class Local( + override val key: String, + @field:StringRes private val id: Int = R.string.errorGeneric + ) : DriveError, Message { + override val message: String + get() = appCtx.getString(id) + + object CachingFailed : Local(key = "cachingFailed", id = R.string.errorCache) + object DownloadFailed : Local(key = "downloadFailed", id = R.string.errorDownload) + object ErrorDeviceStorage : Local(key = "errorDeviceStorage", id = R.string.errorDeviceStorage) + object FileNotFound : Local(key = "fileNotFound") + object LocalError : Local(key = "localError") + object MoveLocalError : Local(key = "moveLocalError", id = R.string.errorMove) + object PhotoAssetNoLongerExists : Local(key = "photoAssetNoLongerExists") + object PhotoLibraryWriteAccessDenied : Local(key = "writeAccessDenied", id = R.string.errorPhotoLibraryAccessLimited) + object SearchCancelled : Local(key = "searchCancelled") + object TaskCancelled : Local(key = "taskCancelled") + object TaskExpirationCancelled : Local(key = "taskExpirationCancelled") + object TaskRescheduled : Local(key = "taskRescheduled") + object UnknownError : Local(key = "unknownError") + object UnknownToken : Local(key = "unknownToken") + object UploadOverDataRestricted : Local(key = "uploadOverDataRestricted", id = R.string.uploadOverDataRestrictedError) + } + + sealed interface Network : DriveError, Message { + override val key: String + get() = "networkError" + override val message: String + get() = appCtx.getString(R.string.errorNetwork) + + object NetworkError : Network + } + + sealed interface Server : DriveError { + sealed class ServerPlurals( + override val key: String, + @field:PluralsRes private val id: Int + ) : Server, Plurals { + override fun message(quantity: Int): String = appCtx.resources.getQuantityString(id, quantity, quantity) + } + + sealed class ServerError( + override val key: String, + @field:StringRes private val id: Int = R.string.errorGeneric + ) : Server, Message { + override val message: String + get() = appCtx.getString(id) + } + + object CategoryAlreadyExists : ServerError(key = "category_already_exist_error", id = R.string.errorCategoryAlreadyExists) + object Conflict : ServerError(key = "conflict_error", id = R.string.errorConflict) + object DestinationAlreadyExists : ServerError(key = "destination_already_exists", id = R.string.errorFileAlreadyExists) + object DownloadPermission : ServerError(key = "you_must_add_at_least_one_file", id = R.string.errorDownloadPermission) + object DriveMaintenance : ServerError(key = "drive_is_in_maintenance_error", id = R.string.driveMaintenanceDescription) + object FileAlreadyExistsError : ServerError(key = "file_already_exists_error", id = R.string.errorFileAlreadyExists) + object Forbidden : ServerError(key = "forbidden_error", id = R.string.accessDeniedTitle) + object InvalidCursorError : ServerError(key = "invalid_cursor_error") + object InvalidUploadTokenError : ServerError(key = "invalid_upload_token_error") + object LimitExceededError : ServerError(key = "limit_exceeded_error", id = R.string.errorLimitExceeded) + object LockError : ServerError(key = "lock_error", id = R.string.errorFileLocked) + object NoDrive : ServerError(key = "no_drive") + object NotAuthorized : ServerError(key = "not_authorized") + object ObjectNotFound : ServerError(key = "object_not_found", id = R.string.uploadFolderNotFoundError) + object ProductBlocked : ServerPlurals(key = "product_blocked", id = R.plurals.driveBlockedDescription) + object ProductMaintenance : ServerError(key = "product_maintenance", id = R.string.driveMaintenanceDescription) + object QuotaExceededError : ServerError(key = "quota_exceeded_error", id = R.string.notEnoughStorageDescription1) + object RefreshToken : ServerError(key = "refreshToken") + object Generic : ServerError(key = "serverError") + object ShareLinkAlreadyExists : ServerError(key = "file_share_link_already_exists", id = R.string.errorShareLink) + object StillUploadingError : ServerError(key = "still_uploading_error", id = R.string.errorStillUploading) + object UploadDestinationNotFoundError : ServerError(key = "upload_destination_not_found_error") + object UploadDestinationNotWritableError : ServerError(key = "upload_destination_not_writable_error") + object UploadError : ServerError(key = "upload_error") + object UploadFailedError : ServerError(key = "upload_failed_error") + object UploadNotTerminated : ServerError(key = "upload_not_terminated") + object UploadNotTerminatedError : ServerError(key = "upload_not_terminated_error") + object UploadTokenCanceled : ServerError(key = "upload_token_canceled") + object UploadTokenIsNotValid : ServerError(key = "upload_token_is_not_valid") + } + + + companion object { + fun find(key: String?): DriveError? = key?.let { allValues.find { it.key == key } } + + private val allValues: List by lazy { buildAllValuesList() } + + private fun buildAllValuesList(): List { + return Local::class.values() + Network::class.values() + ServerError::class.values() + ServerPlurals::class.values() + } + + private inline fun KClass.values(): List = + sealedSubclasses.map { it.objectInstance as DriveError } + + } +} From 9e09eb594f81f0f140f78726ed2c83a6442148d1 Mon Sep 17 00:00:00 2001 From: Benjamin Vadon Date: Wed, 22 Apr 2026 09:12:43 +0200 Subject: [PATCH 5/8] chore: Apply feedback clean error when no error and add error on each manageError call --- .../main/java/com/infomaniak/drive/data/api/UploadTask.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/infomaniak/drive/data/api/UploadTask.kt b/app/src/main/java/com/infomaniak/drive/data/api/UploadTask.kt index a3423cce30..fdbf921dca 100644 --- a/app/src/main/java/com/infomaniak/drive/data/api/UploadTask.kt +++ b/app/src/main/java/com/infomaniak/drive/data/api/UploadTask.kt @@ -225,6 +225,7 @@ class UploadTask( okHttpClient = uploadFile.okHttpClient ) if (!closedSessionResponse.isSuccess()) closedSessionResponse.manageUploadErrors() + else uploadFile.updateUploadErrorKey(null) } } @@ -412,6 +413,8 @@ class UploadTask( ApiResponse(error = ApiError(description = bodyResponse)) } apiResponse.manageUploadErrors() + } else { + uploadFile.updateUploadErrorKey(null) } } @@ -475,14 +478,15 @@ class UploadTask( return ApiRepository.startUploadSession(driveId, sessionBody, okHttpClient).also { if (it.isSuccess()) it.data?.run { uploadFile.updateUploadToken(token, uploadHost) + uploadFile.updateUploadErrorKey(null) } else { - uploadFile.updateUploadErrorKey(it.error?.code) it.manageUploadErrors() } }.data?.uploadHost } private fun ApiResponse.manageUploadErrors() { + uploadFile.updateUploadErrorKey(error?.code) if (error?.exception is ApiControllerNetworkException) throw NetworkException() when (error?.code) { "file_already_exists_error" -> Unit From 8a7b0276c1983049fa07c595a0207150d8a3eaf5 Mon Sep 17 00:00:00 2001 From: Benjamin Vadon Date: Wed, 22 Apr 2026 09:21:17 +0200 Subject: [PATCH 6/8] chore: Apply feedback use map instead of list --- .../com/infomaniak/drive/data/models/up/DriveError.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/infomaniak/drive/data/models/up/DriveError.kt b/app/src/main/java/com/infomaniak/drive/data/models/up/DriveError.kt index 46f7dfad40..7e953d4f33 100644 --- a/app/src/main/java/com/infomaniak/drive/data/models/up/DriveError.kt +++ b/app/src/main/java/com/infomaniak/drive/data/models/up/DriveError.kt @@ -118,16 +118,16 @@ sealed interface DriveError { companion object { - fun find(key: String?): DriveError? = key?.let { allValues.find { it.key == key } } + fun find(key: String?): DriveError? = key?.let { allValues[key] } - private val allValues: List by lazy { buildAllValuesList() } + private val allValues: Map by lazy { buildAllValuesList() } - private fun buildAllValuesList(): List { + private fun buildAllValuesList(): Map { return Local::class.values() + Network::class.values() + ServerError::class.values() + ServerPlurals::class.values() } - private inline fun KClass.values(): List = - sealedSubclasses.map { it.objectInstance as DriveError } + private inline fun KClass.values(): Map = + sealedSubclasses.map { it.objectInstance as DriveError }.associateBy { it.key } } } From 9b5e06e70cb1143741e0e1bf0c22e98d106dd017 Mon Sep 17 00:00:00 2001 From: Benjamin Vadon Date: Wed, 22 Apr 2026 09:26:25 +0200 Subject: [PATCH 7/8] chore: Apply sonar feedback on fun interface --- .../main/java/com/infomaniak/drive/data/models/up/DriveError.kt | 2 +- .../main/java/com/infomaniak/drive/data/sync/UploadMigration.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/infomaniak/drive/data/models/up/DriveError.kt b/app/src/main/java/com/infomaniak/drive/data/models/up/DriveError.kt index 7e953d4f33..6a16a82101 100644 --- a/app/src/main/java/com/infomaniak/drive/data/models/up/DriveError.kt +++ b/app/src/main/java/com/infomaniak/drive/data/models/up/DriveError.kt @@ -28,7 +28,7 @@ import kotlin.reflect.KClass sealed interface DriveError { val key: String - interface Plurals { + fun interface Plurals { fun message(quantity: Int): String } diff --git a/app/src/main/java/com/infomaniak/drive/data/sync/UploadMigration.kt b/app/src/main/java/com/infomaniak/drive/data/sync/UploadMigration.kt index 9d02c9a5ea..044fdb1f1c 100644 --- a/app/src/main/java/com/infomaniak/drive/data/sync/UploadMigration.kt +++ b/app/src/main/java/com/infomaniak/drive/data/sync/UploadMigration.kt @@ -116,7 +116,7 @@ class UploadMigration : RealmMigration { ?.addField("onlyWifiSyncMedia", Boolean::class.java, FieldAttribute.REQUIRED) } - if (oldVersion < 9L) {//stop use of oldVersionTemp as it is useless + if (oldVersion < 9L) { //stop use of oldVersionTemp as it is useless schema.get(UploadFile::class.java.simpleName) ?.addField("_driveErrorKey", String::class.java) } From 090f6c78afecdd40de9a4c15a0180c9f88d59a40 Mon Sep 17 00:00:00 2001 From: Benjamin Vadon Date: Wed, 22 Apr 2026 10:13:39 +0200 Subject: [PATCH 8/8] chore: Apply feedback on error with only exception --- .../main/java/com/infomaniak/drive/data/api/UploadTask.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/infomaniak/drive/data/api/UploadTask.kt b/app/src/main/java/com/infomaniak/drive/data/api/UploadTask.kt index fdbf921dca..fc88f5d0e7 100644 --- a/app/src/main/java/com/infomaniak/drive/data/api/UploadTask.kt +++ b/app/src/main/java/com/infomaniak/drive/data/api/UploadTask.kt @@ -42,6 +42,7 @@ import com.infomaniak.drive.data.api.ApiRepository.uploadEmptyFile import com.infomaniak.drive.data.api.ApiRoutes.uploadChunkUrl import com.infomaniak.drive.data.models.UploadFile import com.infomaniak.drive.data.models.drive.Drive.MaintenanceReason +import com.infomaniak.drive.data.models.up.DriveError import com.infomaniak.drive.data.models.upload.UploadSession import com.infomaniak.drive.data.models.upload.ValidChunks import com.infomaniak.drive.data.services.UploadWorker @@ -486,8 +487,11 @@ class UploadTask( } private fun ApiResponse.manageUploadErrors() { + if (error?.exception is ApiControllerNetworkException) { + uploadFile.updateUploadErrorKey(DriveError.Network.NetworkError.key) + throw NetworkException() + } uploadFile.updateUploadErrorKey(error?.code) - if (error?.exception is ApiControllerNetworkException) throw NetworkException() when (error?.code) { "file_already_exists_error" -> Unit "lock_error" -> throw LockErrorException()