mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 21:33:26 +00:00
Fix a crash when attempting to send a bug report with excessively large logs. (#4243)
* Alert the user when there are excessively large log files.
This commit is contained in:
@@ -17,6 +17,7 @@ enum BugReportScreenViewModelAction {
|
||||
}
|
||||
|
||||
struct BugReportScreenViewState: BindableState {
|
||||
let canSendLogFiles: Bool
|
||||
var screenshot: UIImage?
|
||||
var bindings: BugReportScreenViewStateBindings
|
||||
let isModallyPresented: Bool
|
||||
|
||||
@@ -14,6 +14,8 @@ class BugReportScreenViewModel: BugReportScreenViewModelType, BugReportScreenVie
|
||||
private let bugReportService: BugReportServiceProtocol
|
||||
private let clientProxy: ClientProxyProtocol?
|
||||
|
||||
private let logFiles = Tracing.logFiles
|
||||
|
||||
private let actionsSubject: PassthroughSubject<BugReportScreenViewModelAction, Never> = .init()
|
||||
// periphery:ignore - when set to nil this is automatically cancelled
|
||||
@CancellableTask private var uploadTask: Task<Void, Never>?
|
||||
@@ -29,8 +31,10 @@ class BugReportScreenViewModel: BugReportScreenViewModelType, BugReportScreenVie
|
||||
self.bugReportService = bugReportService
|
||||
self.clientProxy = clientProxy
|
||||
|
||||
let bindings = BugReportScreenViewStateBindings(reportText: "", sendingLogsEnabled: true, canContact: false)
|
||||
super.init(initialViewState: BugReportScreenViewState(screenshot: screenshot,
|
||||
let canSendLogFiles = Self.validate(logFiles)
|
||||
let bindings = BugReportScreenViewStateBindings(reportText: "", sendingLogsEnabled: canSendLogFiles, canContact: false)
|
||||
super.init(initialViewState: BugReportScreenViewState(canSendLogFiles: canSendLogFiles,
|
||||
screenshot: screenshot,
|
||||
bindings: bindings,
|
||||
isModallyPresented: isModallyPresented))
|
||||
}
|
||||
@@ -55,6 +59,23 @@ class BugReportScreenViewModel: BugReportScreenViewModelType, BugReportScreenVie
|
||||
}
|
||||
|
||||
// MARK: Private
|
||||
|
||||
/// Kind of a hack - when a log file balloons in size (e.g. due to a tight loop) the app is terminated by iOS for using
|
||||
/// too much memory. This is because we compare the file size against the upload limit **after** compressing it,
|
||||
/// but in order to compress it we load the whole file into memory.
|
||||
///
|
||||
/// We could fix that, but then the problematic log file would be silently dropped and in reality it is much more valuable
|
||||
/// to have the user contact us to say there's an issue with their logs so we can actually fix whatever is generating the
|
||||
/// excessively large log files.
|
||||
private static func validate(_ logFiles: [URL]) -> Bool {
|
||||
for fileURL in logFiles {
|
||||
if let size = try? FileManager.default.sizeForItem(at: fileURL),
|
||||
size > Double(1024 * 1024 * 1024) { // Consider anything over 1GB to be excessive.
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private func submitBugReport() async {
|
||||
let progressSubject = CurrentValueSubject<Double, Never>(0.0)
|
||||
@@ -81,7 +102,7 @@ class BugReportScreenViewModel: BugReportScreenViewModelType, BugReportScreenVie
|
||||
ed25519: ed25519,
|
||||
curve25519: curve25519,
|
||||
text: context.reportText,
|
||||
includeLogs: context.sendingLogsEnabled,
|
||||
logFiles: context.sendingLogsEnabled ? logFiles : nil,
|
||||
canContact: context.canContact,
|
||||
githubLabels: [],
|
||||
files: files)
|
||||
|
||||
@@ -14,6 +14,7 @@ struct BugReportScreen: View {
|
||||
|
||||
@Bindable var context: BugReportScreenViewModel.Context
|
||||
|
||||
var canSendLogFiles: Bool { context.viewState.canSendLogFiles }
|
||||
var photosPickerTitle: String { context.viewState.screenshot == nil ? L10n.screenBugReportAttachScreenshot : L10n.screenBugReportEditScreenshot }
|
||||
|
||||
var body: some View {
|
||||
@@ -56,15 +57,23 @@ struct BugReportScreen: View {
|
||||
|
||||
private var sendLogsSection: some View {
|
||||
Section {
|
||||
ListRow(label: .plain(title: L10n.screenBugReportIncludeLogs),
|
||||
kind: .toggle($context.sendingLogsEnabled))
|
||||
.accessibilityIdentifier(A11yIdentifiers.bugReportScreen.sendLogs)
|
||||
if canSendLogFiles {
|
||||
ListRow(label: .plain(title: L10n.screenBugReportIncludeLogs),
|
||||
kind: .toggle($context.sendingLogsEnabled))
|
||||
.accessibilityIdentifier(A11yIdentifiers.bugReportScreen.sendLogs)
|
||||
}
|
||||
ListRow(label: .plain(title: L10n.screenBugReportViewLogs),
|
||||
kind: .navigationLink { context.send(viewAction: .viewLogs) })
|
||||
.accessibilityIdentifier(A11yIdentifiers.bugReportScreen.sendLogs)
|
||||
} footer: {
|
||||
Text(L10n.screenBugReportLogsDescription)
|
||||
.compoundListSectionFooter()
|
||||
if canSendLogFiles {
|
||||
Text(L10n.screenBugReportLogsDescription)
|
||||
.compoundListSectionFooter()
|
||||
} else {
|
||||
Label(L10n.screenBugReportIncludeLogsError, icon: \.errorSolid, iconSize: .xSmall, relativeTo: .compound.bodySM)
|
||||
.foregroundStyle(.compound.textCriticalPrimary)
|
||||
.compoundListSectionFooter()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user