From 30aa8574633b3be4381e342a60cdd5bc68895730 Mon Sep 17 00:00:00 2001 From: Andy Uhnak Date: Fri, 11 Nov 2022 10:28:04 +0000 Subject: [PATCH] Log decryption errors separately --- .../RoomEvent/MXRoomEventDecryption.swift | 100 +++++++++++++----- .../Utils/Logs/MXAnalyticsDestination.swift | 2 +- changelog.d/pr-1632.change | 1 + 3 files changed, 75 insertions(+), 28 deletions(-) create mode 100644 changelog.d/pr-1632.change diff --git a/MatrixSDK/Crypto/Algorithms/RoomEvent/MXRoomEventDecryption.swift b/MatrixSDK/Crypto/Algorithms/RoomEvent/MXRoomEventDecryption.swift index d8bddbbebc..62adc9ec2e 100644 --- a/MatrixSDK/Crypto/Algorithms/RoomEvent/MXRoomEventDecryption.swift +++ b/MatrixSDK/Crypto/Algorithms/RoomEvent/MXRoomEventDecryption.swift @@ -43,6 +43,10 @@ protocol MXRoomEventDecrypting: Actor { actor MXRoomEventDecryption: MXRoomEventDecrypting { typealias SessionId = String typealias EventId = String + + // `Megolm` error does not currently expose the type of "missing keys" error, so have to match against + // hardcoded non-localized error message. Will be changed in future PR + private static let MissingKeysMessage = "decryption failed because the room key is missing" private let handler: MXCryptoRoomEventDecrypting private var undecryptedEvents: [SessionId: [EventId: MXEvent]] @@ -117,34 +121,10 @@ actor MXRoomEventDecryption: MXRoomEventDecrypting { log.debug("Successfully decrypted event `\(result.clearEvent["type"] ?? "unknown")`") return result - // `Megolm` error does not currently expose the type of "missing keys" error, so have to match against - // hardcoded non-localized error message. Will be changed in future PR - } catch DecryptionError.Megolm(message: "decryption failed because the room key is missing") { - if undecryptedEvents[sessionId] == nil { - log.error("Failed to decrypt one or more events due to missing room keys", context: [ - "session_id": sessionId, - "details": "further errors for the same key will be supressed" - ]) - } - - addUndecryptedEvent(event) - - let result = MXEventDecryptionResult() - result.error = NSError( - domain: MXDecryptingErrorDomain, - code: Int(MXDecryptingErrorUnknownInboundSessionIdCode.rawValue), - userInfo: [ - NSLocalizedDescriptionKey: MXDecryptingErrorUnknownInboundSessionIdReason - ] - ) - return result + } catch let error as DecryptionError { + return handleDecryptionError(for: event, sessionId: sessionId, error: error) } catch { - log.error("Failed to decrypt event", context: error) - addUndecryptedEvent(event) - - let result = MXEventDecryptionResult() - result.error = error - return result + return handleGenericError(for: event, sessionId: sessionId, error: error) } } @@ -220,6 +200,72 @@ actor MXRoomEventDecryption: MXRoomEventDecrypting { } return sessionId } + + // MARK: - Error handling + + private func handleDecryptionError(for event: MXEvent, sessionId: String, error: DecryptionError) -> MXEventDecryptionResult { + switch error { + case .Identifier(let message): + log.error("Failed to decrypt event due to identifier", context: [ + "session_id": sessionId, + "message": message, + "error": error + ]) + return trackedDecryptionResult(for: event, error: error) + + case .Serialization(let message): + log.error("Failed to decrypt event due to serialization", context: [ + "session_id": sessionId, + "message": message, + "error": error + ]) + return trackedDecryptionResult(for: event, error: error) + + case .Megolm(let message): + if message == Self.MissingKeysMessage { + if undecryptedEvents[sessionId] == nil { + log.error("Failed to decrypt event(s) due to missing room keys", context: [ + "session_id": sessionId, + "message": message, + "error": error, + "details": "further errors for the same key will be supressed", + ]) + } + + let keysError = NSError( + domain: MXDecryptingErrorDomain, + code: Int(MXDecryptingErrorUnknownInboundSessionIdCode.rawValue), + userInfo: [ + NSLocalizedDescriptionKey: MXDecryptingErrorUnknownInboundSessionIdReason + ] + ) + return trackedDecryptionResult(for: event, error: keysError) + } else { + log.error("Failed to decrypt event due to serialization", context: [ + "session_id": sessionId, + "message": message, + "error": error + ]) + return trackedDecryptionResult(for: event, error: error) + } + } + } + + private func handleGenericError(for event: MXEvent, sessionId: String, error: Error) -> MXEventDecryptionResult { + log.error("Failed to decrypt event", context: [ + "session_id": sessionId, + "error": error + ]) + return trackedDecryptionResult(for: event, error: error) + } + + private func trackedDecryptionResult(for event: MXEvent, error: Error) -> MXEventDecryptionResult { + addUndecryptedEvent(event) + + let result = MXEventDecryptionResult() + result.error = error + return result + } } #endif diff --git a/MatrixSDK/Utils/Logs/MXAnalyticsDestination.swift b/MatrixSDK/Utils/Logs/MXAnalyticsDestination.swift index b3a82cb2bb..c7b8ef31c8 100644 --- a/MatrixSDK/Utils/Logs/MXAnalyticsDestination.swift +++ b/MatrixSDK/Utils/Logs/MXAnalyticsDestination.swift @@ -45,7 +45,7 @@ class MXAnalyticsDestination: BaseDestination { return dictionary } else if let error = context as? Error { return [ - "error": error.localizedDescription + "error": error ] } else { return [ diff --git a/changelog.d/pr-1632.change b/changelog.d/pr-1632.change new file mode 100644 index 0000000000..cc6c64abd2 --- /dev/null +++ b/changelog.d/pr-1632.change @@ -0,0 +1 @@ +CryptoV2: Log decryption errors separately