Skip to content

Commit 2704cc3

Browse files
committed
errors view take 2
1 parent c2c6934 commit 2704cc3

File tree

5 files changed

+123
-60
lines changed

5 files changed

+123
-60
lines changed

ide-common/src/main/java/org/digma/intellij/plugin/psi/LanguageService.java

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -309,9 +309,39 @@ static Set<EndpointInfo> getEndpointInfos(Project project, String endpointCodeOb
309309

310310
return null;
311311
}
312-
313-
314-
312+
313+
314+
@NotNull
315+
static Map<String, String> findWorkspaceUrisForCodeObjectIdsForErrorStackTrace(Project project, List<String> methodCodeObjectIds) {
316+
317+
//we don't know which language the method ids belong to. so we try all language services and take the
318+
// first one that returns something.
319+
//if its a java or kotlin project then AbstractJvmLanguageService will return something. else maybe the other
320+
//language services will return something. if no language service returns something then return an empty map.
321+
322+
for (SupportedLanguages value : SupportedLanguages.values()) {
323+
324+
try {
325+
Class<? extends LanguageService> clazz = (Class<? extends LanguageService>) Class.forName(value.getLanguageServiceClassName());
326+
LanguageService languageService = project.getService(clazz);
327+
var workspaceUris = languageService.findWorkspaceUrisForCodeObjectIdsForErrorStackTrace(methodCodeObjectIds);
328+
if (workspaceUris != null && !workspaceUris.isEmpty()) {
329+
return workspaceUris;
330+
}
331+
} catch (Throwable e) {
332+
//catch Throwable because there may be errors.
333+
//ignore: some classes will fail to load , for example the CSharpLanguageService
334+
//will fail to load if it's not rider because it depends on rider classes.
335+
//JavaLanguageService will fail to load on rider, etc.
336+
//don't log, it will happen too many times
337+
}
338+
}
339+
340+
return Collections.emptyMap();
341+
}
342+
343+
344+
315345

316346

317347
/**

ide-common/src/main/kotlin/org/digma/intellij/plugin/navigation/MainContentViewSwitcher.kt

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,18 @@ import com.google.common.base.Objects
55
import com.intellij.openapi.components.Service
66
import com.intellij.openapi.components.service
77
import com.intellij.openapi.project.Project
8+
import org.digma.intellij.plugin.navigation.View.Companion.Analytics
89
import org.digma.intellij.plugin.navigation.View.Companion.Assets
10+
import org.digma.intellij.plugin.navigation.View.Companion.Errors
11+
import org.digma.intellij.plugin.navigation.View.Companion.Highlights
12+
import org.digma.intellij.plugin.navigation.View.Companion.Tests
913
import org.digma.intellij.plugin.navigation.View.Companion.getSelected
1014
import org.digma.intellij.plugin.navigation.View.Companion.setSelected
1115
import org.digma.intellij.plugin.navigation.View.Companion.views
1216
import org.digma.intellij.plugin.posthog.ActivityMonitor
1317

1418
//todo: this class is still used while transitioning to a single jcef app but should be removed at some point
19+
@Suppress("unused")
1520
@Service(Service.Level.PROJECT)
1621
class MainContentViewSwitcher(val project: Project) {
1722

@@ -34,23 +39,19 @@ class MainContentViewSwitcher(val project: Project) {
3439
}
3540

3641
fun showErrors() {
37-
showView(View.Errors)
38-
}
39-
40-
fun showErrorDetails() {
41-
showView(View.ErrorDetails)
42+
showView(Errors)
4243
}
4344

4445
fun showTests() {
45-
showView(View.Tests)
46+
showView(Tests)
4647
}
4748

4849
fun showAnalytics() {
49-
showView(View.Analytics)
50+
showView(Analytics)
5051
}
5152

5253
fun showHighlights() {
53-
showView(View.Highlights)
54+
showView(Highlights)
5455
}
5556

5657

@@ -64,6 +65,10 @@ class MainContentViewSwitcher(val project: Project) {
6465
Assets.path = null
6566
}
6667

68+
if (view != Errors) {
69+
Errors.path = null
70+
}
71+
6772
if (view == View.Insights && getSelected() != View.Insights) {
6873
ActivityMonitor.getInstance(project).clearLastInsightsViewed()
6974
}
@@ -94,6 +99,13 @@ class MainContentViewSwitcher(val project: Project) {
9499
Assets.path = null
95100
}
96101
showView(Assets, createHistoryStep)
102+
} else if (segments.size > 1 && segments[1] == "errors") {
103+
if (segments.count() > 2) {
104+
Errors.path = viewId.removePrefix("/errors/")
105+
} else {
106+
Errors.path = null
107+
}
108+
showView(Errors, createHistoryStep)
97109
} else {
98110
View.findById(viewId)?.let { view ->
99111
showView(view, createHistoryStep)
@@ -147,17 +159,14 @@ private constructor(
147159
@JvmStatic
148160
val Errors = View("Errors", "/errors", "errors")
149161

150-
@JvmStatic
151-
val ErrorDetails = View(title = "Error Details", id = "/errors/details", cardName = "errors", isHidden = true)
152-
153162
@JvmStatic
154163
val Tests = View("Tests", "/tests", "tests")
155164

156165
@JvmStatic
157166
val Analytics = View("Analytics", "/analytics", "analytics")
158167

159168

160-
val views = listOf(Highlights, Insights, Assets, Analytics, Errors, ErrorDetails, Tests)
169+
val views = listOf(Highlights, Insights, Assets, Analytics, Errors, Tests)
161170

162171
fun findById(id: String): View? {
163172
return views.find { it.id == id }

src/main/kotlin/org/digma/intellij/plugin/ui/common/TraceButton.kt

Lines changed: 0 additions & 41 deletions
This file was deleted.

src/main/kotlin/org/digma/intellij/plugin/ui/errors/ErrorsMessageRouterHandler.kt

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package org.digma.intellij.plugin.ui.errors
22

3+
import com.fasterxml.jackson.core.type.TypeReference
34
import com.fasterxml.jackson.databind.JsonNode
5+
import com.fasterxml.jackson.databind.ObjectReader
46
import com.fasterxml.jackson.databind.node.NullNode
57
import com.fasterxml.jackson.databind.node.ObjectNode
68
import com.intellij.openapi.project.Project
@@ -24,6 +26,7 @@ class ErrorsMessageRouterHandler(project: Project) : BaseCommonMessageRouterHand
2426
"ERRORS/OPEN_RAW_ERROR_STACK_TRACE_IN_EDITOR" -> openStackTrace(project, requestJsonNode)
2527
"ERRORS/GO_TO_CODE_LOCATION" -> navigateToCode(project, requestJsonNode)
2628
"ERRORS/GET_FILES_URIS" -> getFilesUrls(project, browser, requestJsonNode)
29+
"ERRORS/GO_TO_TRACE" -> goToTrace(project, browser, requestJsonNode)
2730

2831
else -> return false
2932
}
@@ -32,6 +35,7 @@ class ErrorsMessageRouterHandler(project: Project) : BaseCommonMessageRouterHand
3235
}
3336

3437

38+
3539
private fun getErrorsData(project: Project, browser: CefBrowser, requestJsonNode: JsonNode) {
3640
getPayloadFromRequest(requestJsonNode)?.let { payload ->
3741
val spanCodeObjectId = payload.get("spanCodeObjectId")?.takeIf { it !is NullNode }?.asText()
@@ -43,7 +47,7 @@ class ErrorsMessageRouterHandler(project: Project) : BaseCommonMessageRouterHand
4347
val errorsDataWrapper = objectMapper.createObjectNode()
4448
errorsDataWrapper.set<JsonNode>("errors", errorsData)
4549
val setErrorsDataMessage = SetErrorsDataMessage(errorsDataWrapper)
46-
serializeAndExecuteWindowPostMessageJavaScript(browser, setErrorsDataMessage)
50+
serializeAndExecuteWindowPostMessageJavaScript(browser, setErrorsDataMessage, project)
4751
}
4852
}
4953
}
@@ -56,29 +60,61 @@ class ErrorsMessageRouterHandler(project: Project) : BaseCommonMessageRouterHand
5660
val errorDetailsWrapper = objectMapper.createObjectNode()
5761
errorDetailsWrapper.set<JsonNode>("details", errorDetails)
5862
val setErrorDetailsMessage = SetErrorsDetailsMessage(errorDetailsWrapper)
59-
serializeAndExecuteWindowPostMessageJavaScript(browser, setErrorDetailsMessage)
63+
serializeAndExecuteWindowPostMessageJavaScript(browser, setErrorDetailsMessage, project)
6064
}
6165
}
6266
}
6367

6468
private fun openStackTrace(project: Project, requestJsonNode: JsonNode) {
69+
getPayloadFromRequest(requestJsonNode)?.let { payload ->
70+
val stackTrace = payload.get("stackTrace")?.takeIf { it !is NullNode }?.asText()
71+
if (stackTrace != null) {
72+
ErrorsService.getInstance(project).openRawStackTrace(stackTrace)
73+
}
74+
75+
}
6576
}
6677

6778
private fun navigateToCode(project: Project, requestJsonNode: JsonNode) {
79+
getPayloadFromRequest(requestJsonNode)?.let { payload ->
80+
val uri = payload.get("URI")?.takeIf { it !is NullNode }?.asText()
81+
val lineNumber = payload.get("lineNumber")?.takeIf { it !is NullNode }?.asText() ?: "1"
82+
val lastInstanceCommitId = payload.get("lastInstanceCommitId")?.takeIf { it !is NullNode }?.asText()
83+
84+
if (uri != null) {
85+
ErrorsService.getInstance(project).openErrorFrameWorkspaceFile(uri, lineNumber, lastInstanceCommitId)
86+
}
87+
}
6888
}
6989

7090
private fun getFilesUrls(project: Project, browser: CefBrowser, requestJsonNode: JsonNode) {
7191
getPayloadFromRequest(requestJsonNode)?.let { payload ->
7292

7393
val codeObjectIds = payload.get("codeObjectIds")
94+
val reader: ObjectReader = objectMapper.readerFor(object : TypeReference<List<String>>() {})
95+
val list: List<String> = reader.readValue(codeObjectIds)
7496

97+
val workspaceUrls = ErrorsService.getInstance(project).getWorkspaceUris(list)
7598

7699
val filesUrlsWrapper = objectMapper.createObjectNode()
77-
filesUrlsWrapper.set<ObjectNode>("filesURIs", objectMapper.createObjectNode())
100+
filesUrlsWrapper.set<ObjectNode>("filesURIs", objectMapper.valueToTree<JsonNode>(workspaceUrls))
78101
val setFilesUrlsMessage = SetFilesUrlsMessage(filesUrlsWrapper)
79-
serializeAndExecuteWindowPostMessageJavaScript(browser, setFilesUrlsMessage)
102+
serializeAndExecuteWindowPostMessageJavaScript(browser, setFilesUrlsMessage, project)
80103

81104
}
82105
}
83106

107+
108+
private fun goToTrace(project: Project, browser: CefBrowser, requestJsonNode: JsonNode) {
109+
getPayloadFromRequest(requestJsonNode)?.let { payload ->
110+
val traceId = payload.get("traceId")?.takeIf { it !is NullNode }?.asText()
111+
val spanName = payload.get("spanName")?.takeIf { it !is NullNode }?.asText()
112+
val spanCodeObjectId = payload.get("spanCodeObjectId")?.takeIf { it !is NullNode }?.asText()
113+
114+
if (traceId != null && spanName != null) {
115+
ErrorsService.getInstance(project).openTrace(traceId, spanName, spanCodeObjectId)
116+
}
117+
}
118+
}
119+
84120
}

src/main/kotlin/org/digma/intellij/plugin/ui/errors/ErrorsService.kt

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ import com.intellij.openapi.components.service
66
import com.intellij.openapi.diagnostic.Logger
77
import com.intellij.openapi.project.Project
88
import org.digma.intellij.plugin.analytics.AnalyticsService
9+
import org.digma.intellij.plugin.common.EDT
10+
import org.digma.intellij.plugin.jaegerui.JaegerUIService
911
import org.digma.intellij.plugin.log.Log
12+
import org.digma.intellij.plugin.psi.LanguageService
13+
import org.digma.intellij.plugin.service.EditorService
1014

1115

1216
@Service(Service.Level.PROJECT)
@@ -43,5 +47,30 @@ class ErrorsService(val project: Project) : Disposable {
4347
}
4448
}
4549

50+
fun getWorkspaceUris(methodCodeObjectIds: List<String>): Map<String, String> {
51+
try {
52+
return LanguageService.findWorkspaceUrisForCodeObjectIdsForErrorStackTrace(project, methodCodeObjectIds)
53+
} catch (e: Throwable) {
54+
Log.warnWithException(logger, project, e, "error in getWorkspaceUrls")
55+
return mapOf()
56+
}
57+
}
58+
59+
fun openErrorFrameWorkspaceFile(workspaceUrl: String, lineNumber: String, lastInstanceCommitId: String?) {
60+
EDT.ensureEDT {
61+
EditorService.getInstance(project).openErrorFrameWorkspaceFileInEditor(workspaceUrl, lastInstanceCommitId, lineNumber.toInt())
62+
}
63+
}
64+
65+
66+
fun openRawStackTrace(stackTrace: String) {
67+
EDT.ensureEDT {
68+
EditorService.getInstance(project).openRawStackTrace(stackTrace)
69+
}
70+
}
71+
72+
fun openTrace(traceId: String, spanName: String, spanCodeObjectId: String?) {
73+
JaegerUIService.getInstance(project).openEmbeddedJaeger(traceId, spanName, spanCodeObjectId, true)
74+
}
4675

4776
}

0 commit comments

Comments
 (0)