Skip to content

Commit 1aae2a4

Browse files
authored
Merge pull request #2266 from ahoppen/bsp-failed-to-initialize
If a BSP server fails to initialize, show the error message to the user
2 parents d1dd4a5 + 3f9dedd commit 1aae2a4

File tree

2 files changed

+57
-9
lines changed

2 files changed

+57
-9
lines changed

Sources/BuildServerIntegration/BuildServerManager.swift

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -329,8 +329,10 @@ package actor BuildServerManager: QueueBasedMessageHandler {
329329
/// preferred over `buildServerAdapter` because no messages must be sent to the build server before initialization
330330
/// finishes.
331331
private var buildServerAdapterAfterInitialized: BuildServerAdapter? {
332-
get async {
333-
_ = await initializeResult.value
332+
get async throws {
333+
guard await initializeResult.value != nil else {
334+
throw ResponseError.unknown("Build server failed to initialize")
335+
}
334336
return buildServerAdapter
335337
}
336338
}
@@ -505,8 +507,9 @@ package actor BuildServerManager: QueueBasedMessageHandler {
505507
logger.fault("If we have a connectionToBuildServer, we must have had a buildServerSpec")
506508
return nil
507509
}
508-
let initializeResponse = await orLog("Initializing build server") {
509-
try await buildServerAdapter.send(
510+
let initializeResponse: InitializeBuildResponse?
511+
do {
512+
initializeResponse = try await buildServerAdapter.send(
510513
InitializeBuildRequest(
511514
displayName: "SourceKit-LSP",
512515
version: "",
@@ -515,7 +518,19 @@ package actor BuildServerManager: QueueBasedMessageHandler {
515518
capabilities: BuildClientCapabilities(languageIds: [.c, .cpp, .objective_c, .objective_cpp, .swift])
516519
)
517520
)
521+
} catch {
522+
initializeResponse = nil
523+
let errorMessage: String
524+
if let error = error as? ResponseError {
525+
errorMessage = error.message
526+
} else {
527+
errorMessage = "\(error)"
528+
}
529+
connectionToClient.send(
530+
ShowMessageNotification(type: .error, message: "Failed to initialize build server: \(errorMessage)")
531+
)
518532
}
533+
519534
if let initializeResponse, !(initializeResponse.sourceKitData?.sourceKitOptionsProvider ?? false),
520535
case .external(let externalBuildServerAdapter) = buildServerAdapter
521536
{
@@ -559,7 +574,7 @@ package actor BuildServerManager: QueueBasedMessageHandler {
559574
package func shutdown() async {
560575
// Clear any pending work done progresses from the build server.
561576
self.workDoneProgressManagers.removeAll()
562-
guard let buildServerAdapter = await self.buildServerAdapterAfterInitialized else {
577+
guard let buildServerAdapter = try? await self.buildServerAdapterAfterInitialized else {
563578
return
564579
}
565580
await orLog("Sending shutdown request to build server") {
@@ -898,7 +913,7 @@ package actor BuildServerManager: QueueBasedMessageHandler {
898913
in target: BuildTargetIdentifier,
899914
language: Language
900915
) async throws -> FileBuildSettings? {
901-
guard let buildServerAdapter = await buildServerAdapterAfterInitialized else {
916+
guard let buildServerAdapter = try await buildServerAdapterAfterInitialized else {
902917
return nil
903918
}
904919
let request = TextDocumentSourceKitOptionsRequest(
@@ -1158,7 +1173,7 @@ package actor BuildServerManager: QueueBasedMessageHandler {
11581173
}
11591174

11601175
private func buildTargets() async throws -> [BuildTargetIdentifier: BuildTargetInfo] {
1161-
guard let buildServerAdapter = await buildServerAdapterAfterInitialized else {
1176+
guard let buildServerAdapter = try await buildServerAdapterAfterInitialized else {
11621177
return [:]
11631178
}
11641179

@@ -1198,7 +1213,7 @@ package actor BuildServerManager: QueueBasedMessageHandler {
11981213
}
11991214

12001215
package func sourceFiles(in targets: Set<BuildTargetIdentifier>) async throws -> [SourcesItem] {
1201-
guard let buildServerAdapter = await buildServerAdapterAfterInitialized, !targets.isEmpty else {
1216+
guard let buildServerAdapter = try await buildServerAdapterAfterInitialized, !targets.isEmpty else {
12021217
return []
12031218
}
12041219

@@ -1414,7 +1429,7 @@ package actor BuildServerManager: QueueBasedMessageHandler {
14141429
// MARK: Informing BuildSererManager about changes
14151430

14161431
package func filesDidChange(_ events: [FileEvent]) async {
1417-
if let buildServerAdapter = await buildServerAdapterAfterInitialized {
1432+
if let buildServerAdapter = try? await buildServerAdapterAfterInitialized {
14181433
await buildServerAdapter.send(OnWatchedFilesDidChangeNotification(changes: events))
14191434
}
14201435

Tests/BuildServerIntegrationTests/ExternalBuildServerTests.swift

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,4 +647,37 @@ final class ExternalBuildServerTests: XCTestCase {
647647
}
648648
try await fulfillmentOfOrThrow(preparationFinished)
649649
}
650+
651+
func testBuildServerFailsToInitialize() async throws {
652+
actor BuildServer: CustomBuildServer {
653+
let inProgressRequestsTracker = CustomBuildServerInProgressRequestTracker()
654+
655+
init(projectRoot: URL, connectionToSourceKitLSP: any Connection) {}
656+
657+
func initializeBuildRequest(_ request: InitializeBuildRequest) async throws -> InitializeBuildResponse {
658+
throw ResponseError.unknown("Initialization failed with bad error")
659+
}
660+
661+
func buildTargetSourcesRequest(_ request: BuildTargetSourcesRequest) async throws -> BuildTargetSourcesResponse {
662+
throw ResponseError.unknown("Not expected to get called")
663+
}
664+
665+
func textDocumentSourceKitOptionsRequest(
666+
_ request: TextDocumentSourceKitOptionsRequest
667+
) async throws -> TextDocumentSourceKitOptionsResponse? {
668+
throw ResponseError.unknown("Not expected to get called")
669+
}
670+
}
671+
672+
let project = try await CustomBuildServerTestProject(
673+
files: [
674+
"Test.swift": """
675+
func 1️⃣myTestFunc() {}
676+
"""
677+
],
678+
buildServer: BuildServer.self
679+
)
680+
let message = try await project.testClient.nextNotification(ofType: ShowMessageNotification.self)
681+
assertContains(message.message, "Initialization failed with bad error")
682+
}
650683
}

0 commit comments

Comments
 (0)