Added the traceback (if any) to error messages displayed to the user.
PiperOrigin-RevId: 207123591
diff --git a/src/TulsiGenerator/BazelErrorExtractor.swift b/src/TulsiGenerator/BazelErrorExtractor.swift
index 032777a..8df4f82 100644
--- a/src/TulsiGenerator/BazelErrorExtractor.swift
+++ b/src/TulsiGenerator/BazelErrorExtractor.swift
@@ -25,14 +25,55 @@
}
static func firstErrorLinesFromString(_ output: String, maxErrors: Int = DefaultErrors) -> String? {
- let errorLines = output.components(separatedBy: "\n").filter({ $0.hasPrefix("ERROR:") })
- if errorLines.isEmpty {
- return nil
+ func isNewLogMessage(_ line: String) -> Bool {
+ for newLogMessagePrefix in ["ERROR:", "INFO:", "WARNING:"] {
+ if line.hasPrefix(newLogMessagePrefix) {
+ return true
+ }
+ }
+ return false
}
- let numErrorLinesToShow = min(errorLines.count, maxErrors)
- var errorSnippet = errorLines.prefix(numErrorLinesToShow).joined(separator: "\n")
- if numErrorLinesToShow < errorLines.count {
+ var errorMessages = [String]()
+ var tracebackErrorMessages = Set<String>()
+ var activeTraceback = [String]()
+
+ for line in output.components(separatedBy: "\n") {
+ if !activeTraceback.isEmpty {
+ if isNewLogMessage(line) {
+ if !errorMessages.isEmpty {
+ let lastMessageIndex = errorMessages.count - 1
+ errorMessages[lastMessageIndex].append(activeTraceback.joined(separator: "\n"))
+ tracebackErrorMessages.insert(errorMessages[lastMessageIndex])
+ }
+ activeTraceback = []
+ } else {
+ activeTraceback.append(line)
+ }
+ } else if (line.hasPrefix("Traceback")) {
+ activeTraceback.append(line)
+ }
+
+ if (line.hasPrefix("ERROR:")) {
+ errorMessages.append(line)
+ }
+ }
+
+ if !activeTraceback.isEmpty && !errorMessages.isEmpty {
+ let lastMessageIndex = errorMessages.count - 1
+ errorMessages[lastMessageIndex].append(activeTraceback.joined(separator: "\n"))
+ tracebackErrorMessages.insert(errorMessages[lastMessageIndex])
+ }
+
+ // Display only up to 'maxErrors' number of errors to the user (including any
+ // associated traceback), but also check if any remaining errors include a traceback.
+ // Errors with a traceback should always be displayed regardless of how many errors are
+ // already being printed.
+ var errorSnippet = errorMessages.prefix(maxErrors).joined(separator: "\n")
+ tracebackErrorMessages.subtract(errorMessages.prefix(maxErrors))
+ errorSnippet.append(tracebackErrorMessages.joined(separator: "\n"))
+
+ if maxErrors < errorMessages.count {
errorSnippet += "\n..."
}
return errorSnippet