Skip to content

Commit 42ef7fb

Browse files
committed
fix: dont connect if no joinLink, show error (#23549)
Signed-off-by: Andre Dietisheim <[email protected]>
1 parent 772d945 commit 42ef7fb

File tree

6 files changed

+71
-36
lines changed

6 files changed

+71
-36
lines changed

src/main/kotlin/com/redhat/devtools/gateway/DevSpacesConnection.kt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@
1111
*/
1212
package com.redhat.devtools.gateway
1313

14-
import com.redhat.devtools.gateway.openshift.DevWorkspaces
15-
import com.redhat.devtools.gateway.openshift.Pods
16-
import com.redhat.devtools.gateway.server.RemoteIDEServer
1714
import com.jetbrains.gateway.thinClientLink.LinkedClientManager
1815
import com.jetbrains.gateway.thinClientLink.ThinClientHandle
1916
import com.jetbrains.rd.util.lifetime.Lifetime
17+
import com.redhat.devtools.gateway.openshift.DevWorkspaces
18+
import com.redhat.devtools.gateway.openshift.Pods
19+
import com.redhat.devtools.gateway.server.RemoteIDEServer
2020
import io.kubernetes.client.openapi.ApiException
2121
import java.io.IOException
2222
import java.net.URI
@@ -52,12 +52,13 @@ class DevSpacesConnection(private val devSpacesContext: DevSpacesContext) {
5252

5353
val remoteIdeServer = RemoteIDEServer(devSpacesContext)
5454
val remoteIdeServerStatus = remoteIdeServer.getStatus()
55-
55+
val joinLink = remoteIdeServerStatus.joinLink
56+
?: throw IOException("Could not connect, remote IDE is not ready. No join link present.")
5657
val client = LinkedClientManager
5758
.getInstance()
5859
.startNewClient(
5960
Lifetime.Eternal,
60-
URI(remoteIdeServerStatus.joinLink),
61+
URI(joinLink),
6162
"",
6263
onConnected,
6364
false

src/main/kotlin/com/redhat/devtools/gateway/DevSpacesConnectionProvider.kt

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
package com.redhat.devtools.gateway
1313

1414
import com.intellij.openapi.application.ApplicationManager
15+
import com.intellij.openapi.application.EDT
1516
import com.intellij.openapi.application.ModalityState
1617
import com.intellij.openapi.diagnostic.thisLogger
1718
import com.intellij.openapi.progress.ProcessCanceledException
@@ -29,6 +30,8 @@ import com.redhat.devtools.gateway.openshift.OpenShiftClientFactory
2930
import com.redhat.devtools.gateway.openshift.kube.KubeConfigBuilder
3031
import com.redhat.devtools.gateway.openshift.kube.isNotFound
3132
import com.redhat.devtools.gateway.openshift.kube.isUnauthorized
33+
import com.redhat.devtools.gateway.util.messageWithoutPrefix
34+
import com.redhat.devtools.gateway.view.ui.Dialogs
3235
import io.kubernetes.client.openapi.ApiException
3336
import kotlinx.coroutines.CompletableDeferred
3437
import kotlinx.coroutines.Dispatchers
@@ -67,9 +70,9 @@ class DevSpacesConnectionProvider : GatewayConnectionProvider {
6770
indicator.setText("Connecting to DevSpace...")
6871
indicator.setIndeterminate(true)
6972

70-
val handle = doConnect(parameters, requestor, indicator) // suspend function assumed
73+
val handle = doConnect(parameters, indicator)
7174

72-
val thinClient = handle?.clientHandle
75+
val thinClient = handle.clientHandle
7376
?: throw RuntimeException("Failed to obtain ThinClientHandle")
7477

7578
indicator.setText("Waiting for remote IDE to start...")
@@ -86,31 +89,32 @@ class DevSpacesConnectionProvider : GatewayConnectionProvider {
8689
onClientClosed(readyDeferred, indicator))
8790

8891
readyDeferred.await()
89-
} catch (err: ApiException) {
92+
} catch (e: ApiException) {
9093
indicator.setText("Connection failed")
91-
Timer(2000) {
92-
indicator.close(DialogWrapper.CANCEL_EXIT_CODE)
93-
}.start()
94-
95-
if (handleUnauthorizedError(err) || handleNotFoundError(err)) {
96-
null
97-
} else {
98-
throw err
94+
delayedClose(indicator)
95+
if (!(handleUnauthorizedError(e) || handleNotFoundError(e))) {
96+
Dialogs.error(e.messageWithoutPrefix() ?: "Could not connect to workspace.", "Connection Error")
9997
}
98+
null
10099
} catch (e: Exception) {
101100
indicator.setText("Unexpected error: ${e.message}")
102-
Timer(2000) {
103-
indicator.close(DialogWrapper.CANCEL_EXIT_CODE)
104-
}.start()
105-
throw e
101+
delayedClose(indicator)
102+
Dialogs.error(e.messageWithoutPrefix() ?: "Could not connect to workspace.", "Connection Error")
103+
null
106104
} finally {
107-
ApplicationManager.getApplication().invokeLater {
105+
withContext(Dispatchers.EDT) {
108106
if (indicator.isShowing) indicator.close(DialogWrapper.OK_EXIT_CODE)
109107
}
110108
}
111109
}
112110
}
113111

112+
private fun delayedClose(indicator: StartupProgressIndicator) {
113+
Timer(2000) {
114+
indicator.close(DialogWrapper.CANCEL_EXIT_CODE)
115+
}.start()
116+
}
117+
114118
private fun onClientPresenceChanged(
115119
readyDeferred: CompletableDeferred<GatewayConnectionHandle?>,
116120
indicator: StartupProgressIndicator,
@@ -162,9 +166,8 @@ class DevSpacesConnectionProvider : GatewayConnectionProvider {
162166
@Throws(IllegalArgumentException::class)
163167
private fun doConnect(
164168
parameters: Map<String, String>,
165-
requestor: ConnectionRequestor,
166169
indicator: ProgressIndicator? = null
167-
): GatewayConnectionHandle? {
170+
): GatewayConnectionHandle {
168171
thisLogger().debug("Launched Dev Spaces connection provider", parameters)
169172

170173
indicator?.text2 = "Preparing connection environment…"
@@ -224,12 +227,10 @@ class DevSpacesConnectionProvider : GatewayConnectionProvider {
224227
"\n\nYou are using token-based authentication.\nUpdate your token in the kubeconfig file."
225228
else ""
226229

227-
withContext(Dispatchers.Main) {
228-
Messages.showErrorDialog(
229-
"Your session has expired.\nPlease log in again to continue.$tokenNote",
230-
"Authentication Required"
231-
)
232-
}
230+
Dialogs.error(
231+
"Your session has expired.\nPlease log in again to continue.$tokenNote",
232+
"Authentication Required"
233+
)
233234
return true
234235
}
235236

@@ -243,9 +244,7 @@ class DevSpacesConnectionProvider : GatewayConnectionProvider {
243244
Please verify your Kubernetes context, namespace, and that the DevWorkspace Operator is installed and running.
244245
""".trimIndent()
245246

246-
withContext(Dispatchers.Main) {
247-
Messages.showErrorDialog(message, "Resource Not Found")
248-
}
247+
Dialogs.error(message, "Resource Not Found")
249248
return true
250249
}
251250

src/main/kotlin/com/redhat/devtools/gateway/server/RemoteIDEServerStatus.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
package com.redhat.devtools.gateway.server
1414

1515
data class RemoteIDEServerStatus(
16-
val joinLink: String,
16+
val joinLink: String?,
1717
val httpLink: String,
1818
val gatewayLink: String,
1919
val appVersion: String,

src/main/kotlin/com/redhat/devtools/gateway/util/ExceptionUtils.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,18 @@
1111
*/
1212
package com.redhat.devtools.gateway.util
1313

14+
1415
fun Throwable.rootMessage(): String {
1516
var cause: Throwable? = this
1617
while (cause?.cause != null) {
1718
cause = cause.cause
1819
}
1920
return cause?.message?.trim()
20-
?: this.message?.substringAfter(":")?.trim()
21+
?: messageWithoutPrefix()
2122
?: "Unknown error"
2223
}
24+
25+
fun Throwable.messageWithoutPrefix(): String? {
26+
return message?.trim()
27+
?: message?.substringAfter(":")?.trim()
28+
}

src/main/kotlin/com/redhat/devtools/gateway/view/steps/DevSpacesRemoteServerConnectionStepView.kt

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
*/
1212
package com.redhat.devtools.gateway.view.steps
1313

14+
import com.intellij.notification.Notifications
1415
import com.redhat.devtools.gateway.DevSpacesBundle
1516
import com.redhat.devtools.gateway.DevSpacesConnection
1617
import com.redhat.devtools.gateway.DevSpacesContext
@@ -31,6 +32,13 @@ import com.intellij.ui.dsl.builder.RightGap
3132
import com.intellij.ui.dsl.builder.panel
3233
import com.intellij.util.ui.JBFont
3334
import com.intellij.util.ui.JBUI
35+
import com.redhat.devtools.gateway.util.messageWithoutPrefix
36+
import com.redhat.devtools.gateway.view.ui.Dialogs
37+
import kotlinx.coroutines.CoroutineScope
38+
import kotlinx.coroutines.Dispatchers
39+
import kotlinx.coroutines.launch
40+
import okhttp3.internal.notify
41+
import org.jetbrains.concurrency.runAsync
3442
import java.awt.Component
3543
import java.awt.EventQueue
3644
import javax.swing.DefaultListModel
@@ -200,7 +208,7 @@ class DevSpacesRemoteServerConnectionStepView(private var devSpacesContext: DevS
200208
)
201209
ApplicationManager.getApplication().invokeLaterOnWriteThread { loaderDialog.show() }
202210

203-
Thread {
211+
CoroutineScope(Dispatchers.IO).launch {
204212
try {
205213
DevSpacesConnection(devSpacesContext).connect(
206214
{
@@ -231,8 +239,9 @@ class DevSpacesRemoteServerConnectionStepView(private var devSpacesContext: DevS
231239
)
232240
refreshStopButton()
233241
thisLogger().error("Remote server connection failed.", e)
242+
Dialogs.error(e.messageWithoutPrefix() ?: "Could not connect to workspace", "Connection Error")
234243
}
235-
}.start()
244+
}
236245
}
237246

238247
private fun waitDevWorkspaceStopped(devWorkspace: DevWorkspace): Boolean {
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.redhat.devtools.gateway.view.ui
2+
3+
import com.intellij.openapi.application.ApplicationManager
4+
import com.intellij.openapi.ui.Messages
5+
import kotlinx.coroutines.Dispatchers
6+
import kotlinx.coroutines.withContext
7+
8+
object Dialogs {
9+
10+
suspend fun error(message: String, title: String) {
11+
withContext(Dispatchers.Main) {
12+
Messages.showMessageDialog(
13+
message,
14+
title,
15+
Messages.getErrorIcon(),
16+
)
17+
}
18+
}
19+
20+
}

0 commit comments

Comments
 (0)