Changed the logging system so that error level logs are not automatically displayed in a modal to the user, instead they are all stored and only combined into one modal when a new `displayPendingErrors()` function is called.
PiperOrigin-RevId: 207947320
diff --git a/src/Tulsi/TulsiProjectDocument.swift b/src/Tulsi/TulsiProjectDocument.swift
index 3f408fc..a2ced92 100644
--- a/src/Tulsi/TulsiProjectDocument.swift
+++ b/src/Tulsi/TulsiProjectDocument.swift
@@ -129,6 +129,7 @@
/// Array of user-facing messages, generally output by the Tulsi generator.
@objc dynamic var messages = [UIMessage]()
+ var errors = [LogMessage]()
lazy var bundleExtension: String = {
TulsiProjectDocument.getTulsiBundleExtension()
@@ -148,6 +149,9 @@
queue: OperationQueue.main) {
[weak self] (notification: Notification) in
guard let item = LogMessage(notification: notification) else {
+ if let showModal = notification.userInfo?["displayErrors"] as? Bool, showModal {
+ self?.displayErrorModal()
+ }
return
}
self?.handleLogMessage(item)
@@ -478,6 +482,29 @@
// MARK: - Private methods
+ // Idempotent function to gather all error messages that have been logged and create a single
+ // error modal to present to the user.
+ private func displayErrorModal() {
+ guard TulsiProjectDocument.showAlertsOnErrors else {
+ return
+ }
+
+ var errorMessages = [String]()
+ var details = [String]()
+
+ for error in errors {
+ errorMessages.append(error.message)
+ if let detail = error.details {
+ details.append(detail)
+ }
+ }
+ errors.removeAll()
+
+ if !errorMessages.isEmpty {
+ ErrorAlertView.displayModalError(errorMessages.joined(separator: "\n"), details: details.joined(separator: "\n"))
+ }
+ }
+
private func handleLogMessage(_ item: LogMessage) {
let fullMessage: String
if let details = item.details {
@@ -489,9 +516,7 @@
switch item.level {
case .Error:
messages.append(UIMessage(text: fullMessage, type: .error))
- if TulsiProjectDocument.showAlertsOnErrors {
- ErrorAlertView.displayModalError(item.message, details: item.details)
- }
+ errors.append(item)
case .Warning:
messages.append(UIMessage(text: fullMessage, type: .warning))
@@ -567,7 +592,7 @@
"and file a bug if appropriate."
alert.alertStyle = .critical
- if let details = details {
+ if let details = details, !details.isEmpty {
alert.text = details
var views: NSArray?
diff --git a/src/TulsiGenerator/TulsiNotifications.swift b/src/TulsiGenerator/TulsiNotifications.swift
index 9a6c968..4d98721 100644
--- a/src/TulsiGenerator/TulsiNotifications.swift
+++ b/src/TulsiGenerator/TulsiNotifications.swift
@@ -56,8 +56,17 @@
public let details: String?
public let context: String?
+ // Sends a notification to display any errors that have been logged with postError.
+ public static func displayPendingErrors() {
+ let userInfo = [ "displayErrors" : true ]
+ NotificationCenter.default.post(name: Notification.Name(rawValue: TulsiMessageNotification),
+ object: nil,
+ userInfo: userInfo)
+ }
+
public static func postError(_ message: String, details: String? = nil, context: String? = nil) {
postMessage(.Error, message: message, details: details, context: context)
+ displayPendingErrors()
}
public static func postWarning(_ message: String, details: String? = nil, context: String? = nil) {
diff --git a/src/TulsiGeneratorIntegrationTests/BazelIntegrationTestCase.swift b/src/TulsiGeneratorIntegrationTests/BazelIntegrationTestCase.swift
index 92e69a4..f95ca78 100644
--- a/src/TulsiGeneratorIntegrationTests/BazelIntegrationTestCase.swift
+++ b/src/TulsiGeneratorIntegrationTests/BazelIntegrationTestCase.swift
@@ -342,6 +342,10 @@
queue: nil) {
[weak self] (notification: Notification) in
guard let item = LogMessage(notification: notification) else {
+ guard !(notification.userInfo?["displayErrors"] as? Bool ?? false) else {
+ return
+ }
+
XCTFail("Invalid message notification received (failed to convert to LogMessage)")
return
}