       process.currentDirectoryPath = workspaceRootURL.path
       process.launch()
       _ = semaphore.wait(timeout: DispatchTime.distantFuture)
+
       guard process.terminationStatus == 0 else {
+        let debugInfo = processDebugInfo ?? "<No Debug Info>"
+        localizedMessageLogger.infoMessage(debugInfo)
+        localizedMessageLogger.error("BazelInfoExtractionFailed",
+                                     comment: "Error message for when a Bazel extractor did not complete successfully. Details are logged separately.",
+                                     details: BazelErrorExtractor.firstErrorLinesFromString(debugInfo))
         throw ExtractorError.buildFailed
       }
 

        let events = try reader.readAllEvents()
        let artifacts = events.flatMap { $0.files.lazy.filter { $0.hasSuffix(".tulsiinfo") } }

        if process.terminationStatus == 0, !artifacts.isEmpty {
          extractedEntries = self.extractRuleEntriesFromArtifacts(artifacts,
                                                                  progressNotifier: progressNotifier)
        } else {

                                                               message: "Extracting info for \(targets.count) rules")

    let semaphore = DispatchSemaphore(value: 0)
    var artifacts = [String]()
    var processDebugInfo: String? = nil
    let process = bazelAspectProcessForTargets(targets.map({ $0.value }),
                                               aspect: "tulsi_sources_aspect",
                                               startupOptions: startupOptions,
