@@ -9,6 +9,7 @@ import com.coder.gateway.sdk.CoderCLIManager
99import com.coder.gateway.sdk.CoderRestClientService
1010import com.coder.gateway.sdk.OS
1111import com.coder.gateway.sdk.humanizeDuration
12+ import com.coder.gateway.sdk.isCancellation
1213import com.coder.gateway.sdk.isWorkerTimeout
1314import com.coder.gateway.sdk.suspendingRetryWithExponentialBackOff
1415import com.coder.gateway.sdk.toURL
@@ -70,6 +71,7 @@ import net.schmizz.sshj.connection.ConnectionException
7071import java.awt.Component
7172import java.awt.FlowLayout
7273import java.util.Locale
74+ import java.util.concurrent.TimeUnit
7375import java.util.concurrent.TimeoutException
7476import javax.swing.ComboBoxModel
7577import javax.swing.DefaultComboBoxModel
@@ -162,6 +164,7 @@ class CoderLocateRemoteProjectStepView(private val setNextButtonEnabled: (Boolea
162164 // Clear contents from the last attempt if any.
163165 cbIDEComment.foreground = UIUtil .getContextHelpForeground()
164166 cbIDEComment.text = CoderGatewayBundle .message(" gateway.connector.view.coder.remoteproject.ide.none.comment" )
167+ cbIDE.renderer = IDECellRenderer (CoderGatewayBundle .message(" gateway.connector.view.coder.remoteproject.loading.text" ))
165168 ideComboBoxModel.removeAllElements()
166169 setNextButtonEnabled(false )
167170
@@ -178,42 +181,46 @@ class CoderLocateRemoteProjectStepView(private val setNextButtonEnabled: (Boolea
178181 terminalLink.url = coderClient.coderURL.withPath(" /@${coderClient.me.username} /${selectedWorkspace.name} /terminal" ).toString()
179182
180183 ideResolvingJob = cs.launch {
181- val ides = suspendingRetryWithExponentialBackOff(
182- label = " retrieve IDEs" ,
183- logger = logger,
184- action= { attempt ->
185- logger.info(" Deploying to ${selectedWorkspace.name} on $deploymentURL (attempt $attempt )" )
186- // Reset text in the select dropdown.
187- withContext(Dispatchers .Main ) {
188- cbIDE.renderer = IDECellRenderer (
189- if (attempt > 1 ) CoderGatewayBundle .message(" gateway.connector.view.coder.remoteproject.retry.text" , attempt)
190- else CoderGatewayBundle .message(" gateway.connector.view.coder.remoteproject.loading.text" ))
191- }
192- val executor = createRemoteExecutor(CoderCLIManager .getHostName(deploymentURL, selectedWorkspace))
193- if (ComponentValidator .getInstance(tfProject).isEmpty) {
194- installRemotePathValidator(executor)
195- }
196- retrieveIDEs(executor, selectedWorkspace)
197- },
198- predicate = { e ->
199- e is ConnectionException || e is TimeoutException
200- || e is SSHException || e is DeployException
201- },
202- update = { _, e, remainingMs ->
203- cbIDEComment.foreground = UIUtil .getErrorForeground()
204- cbIDEComment.text =
205- if (isWorkerTimeout(e)) " Failed to upload worker binary...it may have timed out. Check the command log for more details."
206- else e.message ? : CoderGatewayBundle .message(" gateway.connector.no-details" )
207- cbIDE.renderer =
208- if (remainingMs != null ) IDECellRenderer (CoderGatewayBundle .message(" gateway.connector.view.coder.remoteproject.retry-error.text" , humanizeDuration(remainingMs)))
209- else IDECellRenderer (CoderGatewayBundle .message(" gateway.connector.view.coder.remoteproject.error.text" ), UIUtil .getBalloonErrorIcon())
210- },
211- )
212- if (ides != null ) {
184+ try {
185+ val ides = suspendingRetryWithExponentialBackOff(
186+ action = { attempt ->
187+ logger.info(" Retrieving IDEs...(attempt $attempt )" )
188+ val executor = createRemoteExecutor(CoderCLIManager .getHostName(deploymentURL, selectedWorkspace))
189+ if (ComponentValidator .getInstance(tfProject).isEmpty) {
190+ installRemotePathValidator(executor)
191+ }
192+ retrieveIDEs(executor, selectedWorkspace)
193+ },
194+ retryIf = {
195+ it is ConnectionException || it is TimeoutException
196+ || it is SSHException || it is DeployException
197+ },
198+ onError = { attempt, nextMs, e ->
199+ logger.error(" Failed to retrieve IDEs (attempt $attempt ; will retry in $nextMs ms)" )
200+ cbIDEComment.foreground = UIUtil .getErrorForeground()
201+ cbIDEComment.text =
202+ if (isWorkerTimeout(e)) " Failed to upload worker binary...it may have timed out. Check the command log for more details."
203+ else e.message ? : CoderGatewayBundle .message(" gateway.connector.no-details" )
204+ },
205+ onCountdown = { attempt, remainingMs ->
206+ cbIDE.renderer =
207+ if (remainingMs == null ) IDECellRenderer (CoderGatewayBundle .message(" gateway.connector.view.coder.remoteproject.error.text" ), UIUtil .getBalloonErrorIcon())
208+ else if (remainingMs < TimeUnit .SECONDS .toMillis(1 )) IDECellRenderer (CoderGatewayBundle .message(" gateway.connector.view.coder.remoteproject.retry.text" , attempt))
209+ else IDECellRenderer (CoderGatewayBundle .message(" gateway.connector.view.coder.remoteproject.retry-error.text" , humanizeDuration(remainingMs)))
210+ },
211+ )
213212 withContext(Dispatchers .Main ) {
214213 ideComboBoxModel.addAll(ides)
215214 cbIDE.selectedIndex = 0
216215 }
216+ } catch (e: Exception ) {
217+ if (isCancellation(e)) {
218+ logger.info(" Connection canceled due to ${e.javaClass} " )
219+ } else {
220+ logger.error(" Failed to retrieve IDEs (will not retry)" , e)
221+ cbIDEComment.foreground = UIUtil .getErrorForeground()
222+ cbIDEComment.text = e.message ? : CoderGatewayBundle .message(" gateway.connector.no-details" )
223+ }
217224 }
218225 }
219226 }
0 commit comments