Skip to content

Commit 5ca54d3

Browse files
david-allisonmikehardy
authored andcommitted
fix(media-import): handle OutOfMemoryError
The OOM is due to copying the file into a byte array so we can recover from it We will work around this issue later, so the main aim is to not crash * Image/Video: Shows dialog after fragment is closed * Paste: Shows snackbar * API: Fails silently (as other exceptions do) Fixes 19579 Issue 19578
1 parent 8a80280 commit 5ca54d3

File tree

3 files changed

+21
-2
lines changed

3 files changed

+21
-2
lines changed

AnkiDroid/src/main/java/com/ichi2/anki/MediaRegistration.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ object MediaRegistration {
4747
/** [Something wrong wrong][R.string.multimedia_editor_something_wrong] */
4848
data object GenericError : MediaError()
4949

50+
/** [Something went wrong, please try again[R.string.something_wrong] */
51+
data class GenericErrorTryAgain(
52+
val details: String?,
53+
) : MediaError()
54+
5055
/** [Error converting clipboard image to png][R.string.multimedia_editor_png_paste_error] */
5156
class ConversionError(
5257
val message: String,
@@ -64,6 +69,7 @@ object MediaRegistration {
6469
fun toHumanReadableString(context: Context): String =
6570
when (this) {
6671
is GenericError -> context.getString(R.string.multimedia_editor_something_wrong)
72+
is GenericErrorTryAgain -> context.getString(R.string.something_wrong) + details?.let { "\n\n$it" }.orEmpty()
6773
is ConversionError -> context.getString(R.string.multimedia_editor_png_paste_error, message)
6874
is ImageTooLarge -> context.getString(R.string.note_editor_image_too_large)
6975
is VideoTooLarge -> context.getString(R.string.note_editor_video_too_large)
@@ -116,6 +122,11 @@ object MediaRegistration {
116122
Timber.w(e, "Failed to paste media")
117123
showError(MediaError.GenericError)
118124
null
125+
} catch (ex: OutOfMemoryError) {
126+
CrashReportService.sendExceptionReport(ex, "onPaste", additionalInfo = null, onlyIfSilent = true)
127+
Timber.w(ex, "Failed to paste media")
128+
showError(MediaError.GenericErrorTryAgain(details = ex.toString()))
129+
null
119130
}
120131

121132
/**

AnkiDroid/src/main/java/com/ichi2/anki/NoteEditorFragment.kt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2080,7 +2080,7 @@ class NoteEditorFragment :
20802080
index: Int,
20812081
field: IField,
20822082
) {
2083-
lifecycleScope.launch {
2083+
launchCatchingTask {
20842084
val note = getCurrentMultimediaEditableNote()
20852085
note.setField(index, field)
20862086
val fieldEditText = editFields!![index]
@@ -2089,7 +2089,12 @@ class NoteEditorFragment :
20892089
// This goes before setting formattedValue to update
20902090
// media paths with the checksum when they have the same name
20912091
withCol {
2092-
NoteService.importMediaToDirectory(this, field)
2092+
try {
2093+
NoteService.importMediaToDirectory(this, field)
2094+
} catch (oomError: OutOfMemoryError) {
2095+
// TODO: a 'retry' flow would be possible here
2096+
throw Exception(oomError)
2097+
}
20932098
}
20942099

20952100
// Completely replace text for text fields (because current text was passed in)

AnkiDroid/src/main/java/com/ichi2/anki/provider/CardContentProvider.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,6 +1044,9 @@ class CardContentProvider : ContentProvider() {
10441044
val uriFromF = Uri.fromFile(f)
10451045
Timber.d("insert -> MEDIA: uriFromF = %s", uriFromF)
10461046
Uri.fromFile(File(fname))
1047+
} catch (e: OutOfMemoryError) {
1048+
Timber.e(e, "insert failed from %s", fileUri)
1049+
null
10471050
} catch (e: IOException) {
10481051
Timber.w(e, "insert failed from %s", fileUri)
10491052
null

0 commit comments

Comments
 (0)