Skip to content

Commit e1beca5

Browse files
committed
#1233 provide plugin error submitter
1 parent 8d66037 commit e1beca5

File tree

3 files changed

+151
-1
lines changed

3 files changed

+151
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package fr.adrienbrault.idea.symfony2plugin;
2+
3+
import com.intellij.openapi.actionSystem.AnAction;
4+
import com.intellij.openapi.actionSystem.AnActionEvent;
5+
import org.jetbrains.annotations.NotNull;
6+
7+
public class TriggerErrorAction extends AnAction {
8+
public TriggerErrorAction() {
9+
super("Error Reporting: Trigger Exception");
10+
}
11+
12+
@Override
13+
public void actionPerformed(@NotNull AnActionEvent e) {
14+
throw new IllegalStateException("this is a bug!");
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
package fr.adrienbrault.idea.symfony2plugin.util.ide;
2+
3+
import com.google.gson.JsonArray;
4+
import com.google.gson.JsonObject;
5+
import com.intellij.ide.DataManager;
6+
import com.intellij.openapi.actionSystem.CommonDataKeys;
7+
import com.intellij.openapi.actionSystem.DataContext;
8+
import com.intellij.openapi.application.ApplicationInfo;
9+
import com.intellij.openapi.application.ApplicationManager;
10+
import com.intellij.openapi.diagnostic.ErrorReportSubmitter;
11+
import com.intellij.openapi.diagnostic.IdeaLoggingEvent;
12+
import com.intellij.openapi.diagnostic.SubmittedReportInfo;
13+
import com.intellij.openapi.extensions.PluginDescriptor;
14+
import com.intellij.openapi.progress.ProgressIndicator;
15+
import com.intellij.openapi.progress.Task;
16+
import com.intellij.openapi.project.Project;
17+
import com.intellij.openapi.ui.Messages;
18+
import com.intellij.util.Consumer;
19+
import org.apache.commons.lang.StringUtils;
20+
import org.apache.http.NameValuePair;
21+
import org.apache.http.client.methods.CloseableHttpResponse;
22+
import org.apache.http.client.methods.HttpPost;
23+
import org.apache.http.client.utils.URLEncodedUtils;
24+
import org.apache.http.entity.StringEntity;
25+
import org.apache.http.impl.client.CloseableHttpClient;
26+
import org.apache.http.impl.client.HttpClientBuilder;
27+
import org.apache.http.message.BasicNameValuePair;
28+
import org.jetbrains.annotations.NotNull;
29+
import org.jetbrains.annotations.Nullable;
30+
31+
import java.awt.*;
32+
import java.util.ArrayList;
33+
34+
/**
35+
* @author Daniel Espendiller <[email protected]>
36+
*/
37+
public class SymfonyPluginErrorReporterSubmitter extends ErrorReportSubmitter {
38+
@Override
39+
public boolean submit(IdeaLoggingEvent @NotNull [] events, @Nullable String additionalInfo, @NotNull Component parentComponent, @NotNull Consumer<? super SubmittedReportInfo> consumer) {
40+
DataContext context = DataManager.getInstance().getDataContext(parentComponent);
41+
Project project = CommonDataKeys.PROJECT.getData(context);
42+
43+
new Task.Backgroundable(project, "Sending Error Report") {
44+
@Override
45+
public void run(@NotNull ProgressIndicator indicator) {
46+
JsonObject jsonObject = new JsonObject();
47+
48+
PluginDescriptor pluginDescriptor = getPluginDescriptor();
49+
50+
String pluginId = pluginDescriptor.getPluginId().toString();
51+
String pluginVersion = pluginDescriptor.getVersion();
52+
53+
jsonObject.addProperty("plugin_id", pluginId);
54+
jsonObject.addProperty("plugin_version", pluginVersion);
55+
56+
if (StringUtils.isNotBlank(additionalInfo)) {
57+
jsonObject.addProperty("comment", additionalInfo);
58+
}
59+
60+
JsonObject ide = new JsonObject();
61+
ApplicationInfo applicationInfo = ApplicationInfo.getInstance();
62+
ide.addProperty("version", applicationInfo.getBuild().withoutProductCode().asString());
63+
ide.addProperty("full_version", applicationInfo.getFullVersion());
64+
ide.addProperty("build", applicationInfo.getBuild().toString());
65+
jsonObject.add("ide", ide);
66+
67+
JsonArray jsonElements = new JsonArray();
68+
69+
for (IdeaLoggingEvent event : events) {
70+
JsonObject jsonEvent = new JsonObject();
71+
jsonEvent.addProperty("message", event.getMessage());
72+
jsonEvent.addProperty("stacktrace", event.getThrowableText());
73+
74+
Throwable throwable = event.getThrowable();
75+
if (throwable != null) {
76+
jsonEvent.addProperty("stacktrace_message", throwable.getMessage());
77+
}
78+
79+
jsonElements.add(jsonEvent);
80+
}
81+
82+
if (!jsonElements.isEmpty()) {
83+
jsonObject.add("events", jsonElements);
84+
}
85+
86+
String s = jsonObject.toString();
87+
88+
ApplicationManager.getApplication().invokeLater(() -> {
89+
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
90+
91+
92+
boolean success = false;
93+
try {
94+
ArrayList<NameValuePair> nameValuePairs = new ArrayList<>() {{
95+
add(new BasicNameValuePair("plugin", pluginId));
96+
}};
97+
98+
HttpPost request = new HttpPost("https://espend.de/report-submitter?" + URLEncodedUtils.format(nameValuePairs, "utf-8"));
99+
request.addHeader("content-type", "application/json");
100+
request.addHeader("x-plugin-version", pluginVersion);
101+
102+
request.setEntity(new StringEntity(s));
103+
CloseableHttpResponse execute = httpClient.execute(request);
104+
httpClient.close();
105+
106+
int statusCode = execute.getStatusLine().getStatusCode();
107+
success = statusCode >= 200 && statusCode < 300;
108+
} catch (Exception ignored) {
109+
}
110+
111+
if (!success) {
112+
Messages.showErrorDialog(parentComponent, "Failed submitting your report!", "Error Report");
113+
return;
114+
}
115+
116+
Messages.showInfoMessage(parentComponent, "Thank you for submitting your report!", "Error Report");
117+
consumer.consume(new SubmittedReportInfo(SubmittedReportInfo.SubmissionStatus.NEW_ISSUE));
118+
});
119+
}
120+
}.queue();
121+
122+
return true;
123+
}
124+
125+
@NotNull
126+
@Override
127+
public String getReportActionText() {
128+
return "Report to espend.de";
129+
}
130+
}

src/main/resources/META-INF/plugin.xml

+5-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,6 @@
114114
</extensions>
115115

116116
<extensions defaultExtensionNs="com.intellij">
117-
118117
<projectService serviceImplementation="fr.adrienbrault.idea.symfony2plugin.Settings"/>
119118

120119
<projectConfigurable instance="fr.adrienbrault.idea.symfony2plugin.SettingsForm"
@@ -266,6 +265,7 @@
266265
serviceImplementation="fr.adrienbrault.idea.symfony2plugin.Symfony2ProjectComponent$ProjectCloseService"/>
267266

268267
<notificationGroup id="Symfony Notifications" displayType="STICKY_BALLOON"/>
268+
<errorHandler implementation="fr.adrienbrault.idea.symfony2plugin.util.ide.SymfonyPluginErrorReporterSubmitter"/>
269269

270270
<localInspection groupPath="Symfony" shortName="PhpRouteMissingInspection" displayName="Route Missing"
271271
groupName="Route"
@@ -636,6 +636,10 @@
636636

637637
<actions>
638638

639+
<actions>
640+
<action class="fr.adrienbrault.idea.symfony2plugin.TriggerErrorAction"/>
641+
</actions>
642+
639643
<action id="Symfony.Menu" class="fr.adrienbrault.idea.symfony2plugin.action.SymfonyContainerServiceBuilder">
640644
<add-to-group group-id="EditorPopupMenu"/>
641645
<add-to-group group-id="ProjectViewPopupMenu" anchor="last"/>

0 commit comments

Comments
 (0)