Skip to content

Commit 2e69ea8

Browse files
dhasani23David Hasani
andauthored
fix(CodeTransform): show link to docs in error notifications (#4155)
* fix(CodeTransform): show link to docs in error notifications * fix detekt issue * detekt issues * more detekt issue * detekt * detekt issues fixed * small comment fix * small string change * better message * small messaging changes * detekt issue * nit: small string change --------- Co-authored-by: David Hasani <[email protected]>
1 parent ea25ebf commit 2e69ea8

File tree

9 files changed

+60
-92
lines changed

9 files changed

+60
-92
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type" : "feature",
3+
"description" : "Amazon Q CodeTransform: show link to docs in error notifications"
4+
}

plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codemodernizer/ArtifactHandler.kt

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ import software.aws.toolkits.jetbrains.services.codemodernizer.model.JobId
2424
import software.aws.toolkits.jetbrains.services.codemodernizer.state.CodeModernizerSessionState
2525
import software.aws.toolkits.jetbrains.services.codemodernizer.state.CodeTransformTelemetryState
2626
import software.aws.toolkits.jetbrains.services.codemodernizer.summary.CodeModernizerSummaryEditorProvider
27-
import software.aws.toolkits.jetbrains.utils.notifyInfo
28-
import software.aws.toolkits.jetbrains.utils.notifyWarn
27+
import software.aws.toolkits.jetbrains.utils.notifyStickyInfo
28+
import software.aws.toolkits.jetbrains.utils.notifyStickyWarn
2929
import software.aws.toolkits.resources.message
3030
import software.aws.toolkits.telemetry.CodeTransformPatchViewerCancelSrcComponents
3131
import software.aws.toolkits.telemetry.CodeTransformVCSViewerSrcComponents
@@ -52,7 +52,7 @@ class ArtifactHandler(private val project: Project, private val clientAdaptor: G
5252
}
5353

5454
private fun notifyDownloadStart() {
55-
notifyInfo(
55+
notifyStickyInfo(
5656
message("codemodernizer.notification.info.download.started.title"),
5757
message("codemodernizer.notification.info.download.started.content"),
5858
project,
@@ -111,9 +111,11 @@ class ArtifactHandler(private val project: Project, private val clientAdaptor: G
111111
codeTransformRunTimeLatency = calculateTotalLatency(downloadStartTime, Instant.now()),
112112
codeTransformJobId = job.id,
113113
codeTransformTotalByteSize = totalDownloadBytes,
114-
codeTransformRuntimeError = telemetryErrorMessage
114+
codeTransformRuntimeError = telemetryErrorMessage,
115115
)
116116
}
117+
} catch (e: Exception) {
118+
return DownloadArtifactResult(null, "")
117119
} finally {
118120
isCurrentlyDownloading.set(false)
119121
}
@@ -142,51 +144,51 @@ class ArtifactHandler(private val project: Project, private val clientAdaptor: G
142144

143145
CodetransformTelemetry.vcsDiffViewerVisible(
144146
codeTransformSessionId = CodeTransformTelemetryState.instance.getSessionId(),
145-
codeTransformJobId = jobId.id
147+
codeTransformJobId = jobId.id,
146148
)
147149

148150
if (dialog.showAndGet()) {
149151
CodetransformTelemetry.vcsViewerSubmitted(
150152
codeTransformSessionId = CodeTransformTelemetryState.instance.getSessionId(),
151153
codeTransformJobId = jobId.id,
152-
codeTransformStatus = CodeModernizerSessionState.getInstance(project).currentJobStatus.toString()
154+
codeTransformStatus = CodeModernizerSessionState.getInstance(project).currentJobStatus.toString(),
153155
)
154156
} else {
155157
CodetransformTelemetry.vcsViewerCanceled(
156158
codeTransformPatchViewerCancelSrcComponents = CodeTransformPatchViewerCancelSrcComponents.CancelButton,
157159
codeTransformSessionId = CodeTransformTelemetryState.instance.getSessionId(),
158160
codeTransformJobId = jobId.id,
159-
codeTransformStatus = CodeModernizerSessionState.getInstance(project).currentJobStatus.toString()
161+
codeTransformStatus = CodeModernizerSessionState.getInstance(project).currentJobStatus.toString(),
160162
)
161163
}
162164
}
163165
}
164166

165167
fun notifyUnableToApplyPatch(patchPath: String) {
166168
LOG.error { "Unable to find patch for file: $patchPath" }
167-
notifyWarn(
169+
notifyStickyWarn(
168170
message("codemodernizer.notification.warn.view_diff_failed.title"),
169171
message("codemodernizer.notification.warn.view_diff_failed.content"),
170172
project,
171-
listOf(),
173+
listOf(openTroubleshootingGuideNotificationAction(TROUBLESHOOTING_URL_DOWNLOAD_DIFF)),
172174
)
173175
}
174176

175177
fun notifyUnableToShowSummary() {
176178
LOG.error { "Unable to display summary" }
177-
notifyWarn(
179+
notifyStickyWarn(
178180
message("codemodernizer.notification.warn.view_summary_failed.title"),
179181
message("codemodernizer.notification.warn.view_summary_failed.content"),
180182
project,
181-
listOf(),
183+
listOf(openTroubleshootingGuideNotificationAction(TROUBLESHOOTING_URL_DOWNLOAD_DIFF)),
182184
)
183185
}
184186

185187
fun displayDiffAction(jobId: JobId) = runReadAction {
186188
CodetransformTelemetry.vcsViewerClicked(
187189
codeTransformVCSViewerSrcComponents = CodeTransformVCSViewerSrcComponents.ToastNotification,
188190
codeTransformSessionId = CodeTransformTelemetryState.instance.getSessionId(),
189-
codeTransformJobId = jobId.id
191+
codeTransformJobId = jobId.id,
190192
)
191193
projectCoroutineScope(project).launch {
192194
displayDiff(jobId)

plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codemodernizer/CodeModernizerManager.kt

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,8 @@ import software.aws.toolkits.jetbrains.services.codemodernizer.toolwindow.CodeMo
5656
import software.aws.toolkits.jetbrains.services.codemodernizer.ui.components.BuildErrorDialog
5757
import software.aws.toolkits.jetbrains.services.codemodernizer.ui.components.PreCodeTransformUserDialog
5858
import software.aws.toolkits.jetbrains.services.codemodernizer.ui.components.ValidationErrorDialog
59-
import software.aws.toolkits.jetbrains.utils.actions.OpenBrowserAction
6059
import software.aws.toolkits.jetbrains.utils.isRunningOnRemoteBackend
61-
import software.aws.toolkits.jetbrains.utils.notifyError
62-
import software.aws.toolkits.jetbrains.utils.notifyInfo
60+
import software.aws.toolkits.jetbrains.utils.notifyStickyError
6361
import software.aws.toolkits.jetbrains.utils.notifyStickyInfo
6462
import software.aws.toolkits.resources.message
6563
import software.aws.toolkits.telemetry.CodeTransformCancelSrcComponents
@@ -286,7 +284,7 @@ class CodeModernizerManager(private val project: Project) : PersistentStateCompo
286284
}
287285

288286
internal fun notifyTransformationStopped() {
289-
notifyInfo(
287+
notifyStickyInfo(
290288
message("codemodernizer.notification.info.transformation_stop.title"),
291289
message("codemodernizer.notification.info.transformation_stop.content"),
292290
project,
@@ -302,23 +300,23 @@ class CodeModernizerManager(private val project: Project) : PersistentStateCompo
302300
}
303301

304302
internal fun notifyTransformationStartStopping() {
305-
notifyInfo(
303+
notifyStickyInfo(
306304
message("codemodernizer.notification.info.transformation_start_stopping.title"),
307305
message("codemodernizer.notification.info.transformation_start_stopping.content"),
308306
project,
309307
)
310308
}
311309

312310
internal fun notifyTransformationStartCannotYetStop() {
313-
notifyError(
311+
notifyStickyError(
314312
message("codemodernizer.notification.info.transformation_start_stopping.failed_title"),
315313
message("codemodernizer.notification.info.transformation_start_stopping.failed_as_job_not_started"),
316314
project,
317315
)
318316
}
319317

320318
internal fun notifyTransformationFailedToStop(message: String) {
321-
notifyError(
319+
notifyStickyError(
322320
message("codemodernizer.notification.info.transformation_start_stopping.failed_title"),
323321
message("codemodernizer.notification.info.transformation_start_stopping.failed_content", message),
324322
project,
@@ -385,7 +383,7 @@ class CodeModernizerManager(private val project: Project) : PersistentStateCompo
385383

386384
is CodeModernizerStartJobResult.UnableToStartJob -> {
387385
CodeModernizerJobCompletedResult.UnableToCreateJob(
388-
message("codemodernizer.notification.warn.unable_to_start_job", result.exception), // TODO maybe not display the entire message
386+
message("codemodernizer.notification.warn.unable_to_start_job", result.exception),
389387
true,
390388
)
391389
}
@@ -533,11 +531,6 @@ class CodeModernizerManager(private val project: Project) : PersistentStateCompo
533531
artifactHandler.displayDiffAction(jobId)
534532
}
535533

536-
private fun openTroubleshootingGuideNotificationAction() = OpenBrowserAction(
537-
message("codemodernizer.notification.info.view_troubleshooting_guide"),
538-
url = "https://docs.aws.amazon.com/amazonq/latest/aws-builder-use-ug/code-transformation.html#transform-issues"
539-
)
540-
541534
private fun displaySummaryNotificationAction(jobId: JobId) =
542535
NotificationAction.createSimple(message("codemodernizer.notification.info.modernize_complete.view_summary")) {
543536
artifactHandler.showTransformationSummary(jobId)
@@ -549,7 +542,7 @@ class CodeModernizerManager(private val project: Project) : PersistentStateCompo
549542
codeTransformResultStatusMessage = result.toString(),
550543
codeTransformRunTimeLatency = calculateTotalLatency(CodeTransformTelemetryState.instance.getStartTime(), Instant.now()),
551544
codeTransformLocalJavaVersion = getJavaVersionFromProjectSetting(project),
552-
codeTransformLocalMavenVersion = getMavenVersions(project),
545+
codeTransformLocalMavenVersion = getMavenVersion(project),
553546
)
554547
when (result) {
555548
is CodeModernizerJobCompletedResult.UnableToCreateJob -> notifyJobFailure(
@@ -593,13 +586,13 @@ class CodeModernizerManager(private val project: Project) : PersistentStateCompo
593586
message("codemodernizer.notification.warn.maven_failed.title"),
594587
message("codemodernizer.notification.warn.maven_failed.content"),
595588
project,
596-
listOf(openTroubleshootingGuideNotificationAction()),
589+
listOf(openTroubleshootingGuideNotificationAction(TROUBLESHOOTING_URL_MAVEN_COMMANDS)),
597590
)
598591
is CodeModernizerJobCompletedResult.JobAbortedZipTooLarge -> notifyStickyInfo(
599592
message("codemodernizer.notification.warn.zip_too_large.title"),
600593
message("codemodernizer.notification.warn.zip_too_large.content"),
601594
project,
602-
listOf(openTroubleshootingGuideNotificationAction()),
595+
listOf(openTroubleshootingGuideNotificationAction(TROUBLESHOOTING_URL_PREREQUISITES)),
603596
)
604597
}
605598
}
@@ -636,7 +629,7 @@ class CodeModernizerManager(private val project: Project) : PersistentStateCompo
636629
codeTransformResultStatusMessage = "JobCancelled",
637630
codeTransformRunTimeLatency = calculateTotalLatency(CodeTransformTelemetryState.instance.getStartTime(), Instant.now()),
638631
codeTransformLocalJavaVersion = getJavaVersionFromProjectSetting(project),
639-
codeTransformLocalMavenVersion = getMavenVersions(project),
632+
codeTransformLocalMavenVersion = getMavenVersion(project),
640633
)
641634
}
642635
} catch (e: Exception) {
@@ -647,7 +640,7 @@ class CodeModernizerManager(private val project: Project) : PersistentStateCompo
647640
codeTransformResultStatusMessage = "JobCancelled",
648641
codeTransformRunTimeLatency = calculateTotalLatency(CodeTransformTelemetryState.instance.getStartTime(), Instant.now()),
649642
codeTransformLocalJavaVersion = getJavaVersionFromProjectSetting(project),
650-
codeTransformLocalMavenVersion = getMavenVersions(project),
643+
codeTransformLocalMavenVersion = getMavenVersion(project),
651644
)
652645
}
653646
}
@@ -680,6 +673,12 @@ class CodeModernizerManager(private val project: Project) : PersistentStateCompo
680673
ApplicationManager.getApplication().invokeLater {
681674
runInEdt { ValidationErrorDialog.create(maybeUnknownReason) }
682675
}
676+
notifyStickyInfo(
677+
message("codemodernizer.validationerrordialog.description.title"),
678+
message("codemodernizer.validationerrordialog.description.main"),
679+
project,
680+
listOf(openTroubleshootingGuideNotificationAction(TROUBLESHOOTING_URL_PREREQUISITES)),
681+
)
683682
}
684683

685684
fun getTransformationPlan(): TransformationPlan? = codeTransformationSession?.getTransformationPlan()

plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codemodernizer/CodeModernizerSession.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ class CodeModernizerSession(
231231
it.setRequestProperty(CodeWhispererCodeScanSession.SERVER_SIDE_ENCRYPTION_AWS_KMS_KEY_ID, kmsArn)
232232
}
233233
}
234-
.connect { request ->
234+
.connect { request -> // default connect timeout is 10s
235235
val connection = request.connection as HttpURLConnection
236236
connection.setFixedLengthStreamingMode(fileToUpload.length())
237237
fileToUpload.inputStream().use { inputStream ->
@@ -416,7 +416,6 @@ class CodeModernizerSession(
416416
TransformationStatus.FAILED,
417417
)
418418
) {
419-
// val response = TODO()
420419
val summary = TransformationSummary(
421420
"""
422421
# Transformation summary

plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codemodernizer/CodeTransformUtils.kt

Lines changed: 15 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,15 @@
33

44
package software.aws.toolkits.jetbrains.services.codemodernizer
55

6-
import com.intellij.execution.configurations.GeneralCommandLine
7-
import com.intellij.execution.process.ProcessNotCreatedException
8-
import com.intellij.execution.util.ExecUtil
96
import com.intellij.openapi.application.ApplicationInfo
107
import com.intellij.openapi.module.ModuleUtil
118
import com.intellij.openapi.project.Project
12-
import com.intellij.openapi.util.SystemInfo
139
import com.intellij.openapi.vfs.VfsUtilCore
1410
import com.intellij.openapi.vfs.VirtualFile
1511
import com.intellij.openapi.vfs.VirtualFileManager
1612
import com.intellij.serviceContainer.AlreadyDisposedException
1713
import org.jetbrains.idea.maven.project.MavenProjectsManager
18-
import org.jetbrains.idea.maven.utils.MavenUtil
1914
import org.jetbrains.plugins.gradle.settings.GradleSettings
20-
import org.slf4j.LoggerFactory
2115
import software.amazon.awssdk.awscore.exception.AwsServiceException
2216
import software.amazon.awssdk.core.exception.SdkClientException
2317
import software.amazon.awssdk.services.codewhispererruntime.model.CodeWhispererRuntimeException
@@ -33,9 +27,7 @@ import software.aws.toolkits.core.TokenConnectionSettings
3327
import software.aws.toolkits.core.utils.WaiterUnrecoverableException
3428
import software.aws.toolkits.core.utils.Waiters.waitUntil
3529
import software.aws.toolkits.core.utils.createParentDirectories
36-
import software.aws.toolkits.core.utils.error
3730
import software.aws.toolkits.core.utils.exists
38-
import software.aws.toolkits.core.utils.warn
3931
import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManager
4032
import software.aws.toolkits.jetbrains.core.credentials.pinning.QConnection
4133
import software.aws.toolkits.jetbrains.core.credentials.sso.bearer.BearerTokenProvider
@@ -47,6 +39,8 @@ import software.aws.toolkits.jetbrains.services.codemodernizer.client.GumbyClien
4739
import software.aws.toolkits.jetbrains.services.codemodernizer.model.JobId
4840
import software.aws.toolkits.jetbrains.services.codemodernizer.model.MAVEN_CONFIGURATION_FILE_NAME
4941
import software.aws.toolkits.jetbrains.services.codemodernizer.state.CodeTransformTelemetryState
42+
import software.aws.toolkits.jetbrains.utils.actions.OpenBrowserAction
43+
import software.aws.toolkits.resources.message
5044
import software.aws.toolkits.telemetry.CodetransformTelemetry
5145
import java.io.File
5246
import java.io.FileOutputStream
@@ -94,7 +88,12 @@ val TERMINAL_STATES = setOf(
9488
TransformationStatus.COMPLETED,
9589
)
9690

97-
private val LOG = LoggerFactory.getLogger("CodeTransformUtils")
91+
const val TROUBLESHOOTING_URL_DOWNLOAD_DIFF =
92+
"https://docs.aws.amazon.com/amazonq/latest/aws-builder-use-ug/troubleshooting-code-transformation.html#w24aac14c20c19c11"
93+
const val TROUBLESHOOTING_URL_MAVEN_COMMANDS =
94+
"https://docs.aws.amazon.com/amazonq/latest/aws-builder-use-ug/troubleshooting-code-transformation.html#w24aac14c20c19b7"
95+
const val TROUBLESHOOTING_URL_PREREQUISITES =
96+
"https://docs.aws.amazon.com/amazonq/latest/aws-builder-use-ug/code-transformation.html#prerequisites"
9897

9998
fun String.toVirtualFile() = VirtualFileManager.getInstance().findFileByUrl(VfsUtilCore.pathToUrl(this))
10099
fun Project.moduleFor(path: String) = ModuleUtil.findModuleForFile(
@@ -287,52 +286,13 @@ fun isGradleProject(project: Project) = !GradleSettings.getInstance(project).lin
287286

288287
fun getJavaVersionFromProjectSetting(project: Project): String? = project.tryGetJdk()?.toString()
289288

290-
fun getMavenVersions(project: Project): String {
291-
fun getVersion(mavenCommand: String): String? {
292-
try {
293-
val commandLine = GeneralCommandLine(listOf(mavenCommand, "-v"))
294-
.withWorkDirectory(project.basePath)
295-
.withRedirectErrorStream(true)
296-
val output = ExecUtil.execAndGetOutput(commandLine)
297-
if (output.exitCode == 0) {
298-
return parseMavenVersion(output.stdout)
299-
} else {
300-
LOG.error { "Failed to fetch $mavenCommand version: ${output.stdout}" }
301-
}
302-
} catch (e: ProcessNotCreatedException) {
303-
LOG.warn { "$mavenCommand not set up" }
304-
} catch (e: Exception) {
305-
LOG.error(e) { "Failed to fetch $mavenCommand version" }
306-
}
307-
return null
308-
}
309-
310-
// Get local maven version
311-
val localMavenVersion: String? = getVersion("mvn")
312-
313-
// Get wrapper maven version
314-
val mvnw = if (SystemInfo.isWindows) "./mvnw.cmd" else "./mvnw"
315-
val wrapperMavenVersion: String? = getVersion(mvnw)
316-
317-
// Get user's Maven setting (using bundled vs local vs wrapper)
289+
fun getMavenVersion(project: Project): String {
318290
val mavenSettings = MavenProjectsManager.getInstance(project).getGeneralSettings()
319-
val mavenHome = mavenSettings.getMavenHome()
320-
// Need to detect bundled Maven version that come with IDEA
321-
// The utility returns "Use Maven wrapper" if using wrapper, "Bundled (Maven 3)" if using Bundled Maven, otherwise the local maven version.
322-
val userMavenSetting = MavenUtil.getMavenVersion(mavenHome) ?: mavenHome
323-
324-
return "$wrapperMavenVersion (mvnw) -- $localMavenVersion (mvn) -- user setting: $userMavenSetting"
291+
// should be set to "Bundled (Maven X)" if setup instructions were followed
292+
return mavenSettings.getMavenHome() ?: "Unknown"
325293
}
326294

327-
private fun parseMavenVersion(output: String?): String? {
328-
if (output == null) return null
329-
val mavenVersionIndex = output.indexOf("Apache Maven")
330-
if (mavenVersionIndex == -1) return null
331-
return try {
332-
val mavenVersionString = output.slice(IntRange(mavenVersionIndex + 13, output.length - 1))
333-
mavenVersionString.slice(IntRange(0, output.indexOf(' ') - 1))
334-
} catch (e: StringIndexOutOfBoundsException) {
335-
LOG.error(e) { "Failed to parse Maven version from output: $output" }
336-
null
337-
}
338-
}
295+
fun openTroubleshootingGuideNotificationAction(targetUrl: String) = OpenBrowserAction(
296+
message("codemodernizer.notification.info.view_troubleshooting_guide"),
297+
url = targetUrl
298+
)

plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codemodernizer/model/CodeModernizerArtifact.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ open class CodeModernizerArtifact(
5353
val manifest = loadManifest()
5454
if (manifest.version > maxSupportedVersion) {
5555
// If not supported we can still try to use it, i.e. the versions should largely be backwards compatible
56-
// TODO change to notify that user should consider upgrading the toolkit version.
56+
// Can also notify user to consider upgrading the toolkit version.
5757
LOG.warn { "Unsupported version: ${manifest.version}" }
5858
}
5959
val patches = extractPatches(manifest)

plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codemodernizer/model/CodeModernizerSessionContext.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ data class CodeModernizerSessionContext(
6767
}
6868

6969
/**
70-
* TODO use an approach based on walkTopDown instead of VfsUtil.collectChildrenRecursively(root) in createZipWithModuleFiles.
70+
* Can eventually modify to use an approach based on walkTopDown instead of VfsUtil.collectChildrenRecursively(root) in createZipWithModuleFiles.
7171
* We now recurse the file tree twice and then filter which hurts performance for large projects.
7272
*/
7373
private fun findDirectoriesToExclude(sourceFolder: File): List<File> {

0 commit comments

Comments
 (0)