Return empty result when EmailProvider query fails
In developer mode we still crash for all errors except for malformed MATCH expressions (which are rather easy to generate given that we pass user input to SQLite).
package com.fsck.k9.ui.messagelist
+import android.annotation.SuppressLint
import android.content.ContentResolver
import android.database.Cursor
+import android.database.MatrixCursor
+import android.database.sqlite.SQLiteException
import android.net.Uri
import com.fsck.k9.Account
import com.fsck.k9.Account.SortType
+import com.fsck.k9.K9
import com.fsck.k9.Preferences
import com.fsck.k9.fragment.MLFProjectionInfo
import com.fsck.k9.fragment.MessageListFragmentComparators.ArrivalComparator
@@ -26,6 +30,7 @@ import com.fsck.k9.search.SqlQueryBuilder
import com.fsck.k9.search.getAccounts
import java.util.ArrayList
import java.util.Comparator
+import timber.log.Timber
class MessageListLoader(
private val preferences: Preferences,
@@ -62,6 +67,7 @@ class MessageListLoader(
return MessageListInfo(messageListItems, hasMoreMessages)
}
+ @SuppressLint("Recycle")
private fun loadMessageListForAccount(account: Account, config: MessageListConfig): Cursor? {
val accountUuid = account.uuid
val threadId: String? = getThreadId(config.search)
@@ -110,7 +116,17 @@ class MessageListLoader(
val sortOrder: String = buildSortOrder(config)
- return contentResolver.query(uri, projection, selection, selectionArgs, sortOrder)
+ return try {
+ contentResolver.query(uri, projection, selection, selectionArgs, sortOrder)
+ } catch (e: SQLiteException) {
+ Timber.e(e, "Error querying EmailProvider")
+
+ if (K9.DEVELOPER_MODE && e.message?.contains("malformed MATCH expression") == false) {
+ throw e
+ }
+
+ return MatrixCursor(projection)
+ }
}
private fun getThreadId(search: LocalSearch): String? {
