diagnostic: introduce PluginException.createByClass and logPluginError methods and use them in code

This simplifies code and also allow using these methods from intellij.platform.core module.
This commit is contained in:
nik
2019-01-31 16:02:35 +03:00
parent a0641431ac
commit dcdbb638fa
24 changed files with 102 additions and 42 deletions
@@ -15,7 +15,7 @@
*/
package com.intellij.framework.library;
import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.diagnostic.PluginException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.libraries.*;
import com.intellij.openapi.roots.libraries.ui.LibraryEditorComponent;
@@ -117,7 +117,7 @@ public abstract class DownloadableLibraryType extends LibraryType<LibraryVersion
@NotNull
public Icon getLibraryTypeIcon() {
if (myIcon == null) {
throw PluginManagerCore.createPluginException("'DownloadableLibraryType::getLibraryTypeIcon' isn't overriden or returns 'null' in " + getClass().getName(), null, getClass());
throw PluginException.createByClass("'DownloadableLibraryType::getLibraryTypeIcon' isn't overriden or returns 'null' in " + getClass().getName(), null, getClass());
}
return myIcon;
}
@@ -2,7 +2,7 @@
package com.jetbrains.jsonSchema.impl;
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.diagnostic.PluginException;
import com.intellij.json.JsonUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
@@ -85,7 +85,7 @@ public class JsonSchemaServiceImpl implements JsonSchemaService {
throw e;
}
catch (Exception e) {
Logger.getInstance(JsonSchemaService.class).error(PluginManagerCore.createPluginException(e.getMessage(), e, factory.getClass()));
PluginException.logPluginError(Logger.getInstance(JsonSchemaService.class), e.getMessage(), e, factory.getClass());
}
}
return providers;
@@ -2,7 +2,7 @@
package com.intellij.configurationStore
import com.intellij.configurationStore.statistic.eventLog.FeatureUsageSettingsEvents
import com.intellij.ide.plugins.PluginManagerCore
import com.intellij.diagnostic.PluginException
import com.intellij.notification.NotificationsManager
import com.intellij.openapi.application.AppUIExecutor
import com.intellij.openapi.application.ApplicationManager
@@ -102,7 +102,7 @@ abstract class ComponentStoreImpl : IComponentStore {
throw e
}
catch (e: Exception) {
LOG.error(PluginManagerCore.createPluginException("Cannot init $componentName component state", e, component.javaClass))
PluginException.logPluginError(LOG, "Cannot init $componentName component state", e, component.javaClass)
}
}
@@ -1,7 +1,7 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.configurationStore
import com.intellij.ide.plugins.PluginManagerCore
import com.intellij.diagnostic.PluginException
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.PersistentStateComponent
import com.intellij.openapi.components.StateStorage
@@ -69,7 +69,7 @@ private class StateGetterImpl<S : Any, T : Any>(private val component: Persisten
throw e
}
catch (e: Throwable) {
LOG.error(PluginManagerCore.createPluginException("Cannot get state after load", e, component.javaClass))
PluginException.logPluginError(LOG, "Cannot get state after load", e, component.javaClass)
null
}
@@ -15,6 +15,7 @@
*/
package com.intellij.diagnostic;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.PluginId;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
@@ -25,7 +26,7 @@ import org.jetbrains.annotations.Nullable;
* some contract of IntelliJ Platform. If such exceptions are thrown or logged via {@link com.intellij.openapi.diagnostic.Logger#error(Throwable)}
* method and reported to JetBrains by user, they may be automatically attributed to corresponding plugins.
*
* <p> If the problem is caused by a class, use {@link com.intellij.ide.plugins.PluginManagerCore#createPluginException} to create
* <p> If the problem is caused by a class, use {@link #createByClass} to create
* an instance. If the problem is caused by an extension, implement {@link com.intellij.openapi.extensions.PluginAware} in its extension class
* to get the plugin ID.
*/
@@ -58,4 +59,20 @@ public class PluginException extends RuntimeException {
String message = super.getMessage();
return myPluginId != null ? StringUtil.notNullize(message) + " [Plugin: " + myPluginId + "]" : message;
}
/**
* Creates an exception caused by a problem in a plugin's code.
* @param pluginClass a problematic class which caused the error
*/
public static PluginException createByClass(@NotNull String errorMessage, @Nullable Throwable cause, @NotNull Class pluginClass) {
return PluginProblemReporter.getInstance().createPluginExceptionByClass(errorMessage, cause, pluginClass);
}
/**
* Log an error caused by a problem in a plugin's code.
* @param pluginClass a problematic class which caused the error
*/
public static void logPluginError(@NotNull Logger logger, @NotNull String errorMessage, @Nullable Throwable cause, @NotNull Class pluginClass) {
logger.error(createByClass(errorMessage, cause, pluginClass));
}
}
@@ -0,0 +1,29 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.diagnostic;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ServiceManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
interface PluginProblemReporter {
static PluginProblemReporter getInstance() {
if (ApplicationManager.getApplication() == null) {
//if the application isn't initialized yet return silly implementation which reports all plugins problems as platform ones
return new PluginProblemReporter() {
@NotNull
@Override
public PluginException createPluginExceptionByClass(@NotNull String errorMessage,
@Nullable Throwable cause,
@NotNull Class pluginClass) {
return new PluginException(errorMessage, cause, null);
}
};
}
return ServiceManager.getService(PluginProblemReporter.class);
}
@NotNull
PluginException createPluginExceptionByClass(@NotNull String errorMessage, @Nullable Throwable cause, @NotNull Class pluginClass);
}
@@ -0,0 +1,14 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.diagnostic;
import com.intellij.ide.plugins.PluginManagerCore;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
class PluginProblemReporterImpl implements PluginProblemReporter {
@NotNull
@Override
public PluginException createPluginExceptionByClass(@NotNull String errorMessage, @Nullable Throwable cause, @NotNull Class pluginClass) {
return PluginManagerCore.createPluginException(errorMessage, cause, pluginClass);
}
}
@@ -342,8 +342,7 @@ public class PluginManagerCore {
}
/**
* Creates an exception caused by a problem in a plugin's code.
* @param pluginClass a problematic class which caused the error
* This is an internal method, use {@link PluginException#createByClass(String, Throwable, Class)} instead.
*/
@NotNull
public static PluginException createPluginException(@NotNull String errorMessage, @Nullable Throwable cause,
@@ -409,7 +409,7 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements
// component may have been already loaded by PicoContainer, so fire error only if components are really different
if (!instance.equals(loadedComponent)) {
String errorMessage = "Component name collision: " + componentName + " " + (loadedComponent == null ? "null" : loadedComponent.getClass()) + " and " + instance.getClass();
LOG.error(PluginManagerCore.createPluginException(errorMessage, null, instance.getClass()));
PluginException.logPluginError(LOG, errorMessage, null, instance.getClass());
}
}
else {
@@ -2,7 +2,7 @@
package com.intellij.psi.impl;
import com.google.common.annotations.VisibleForTesting;
import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.diagnostic.PluginException;
import com.intellij.lang.FileASTNode;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.*;
@@ -717,7 +717,7 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
"; file name:" + file.getName() +
"; type:" + file.getFileType() +
"; lang:" + file.getLanguage();
LOG.error(PluginManagerCore.createPluginException(errorMessage, null, file.getLanguage().getClass()));
PluginException.logPluginError(LOG, errorMessage, null, file.getLanguage().getClass());
file.putUserData(BlockSupport.DO_NOT_REPARSE_INCREMENTALLY, Boolean.TRUE);
try {
@@ -727,7 +727,7 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
diffLog.doActualPsiChange(file);
if (oldFileNode.getTextLength() != document.getTextLength()) {
LOG.error(PluginManagerCore.createPluginException("PSI is broken beyond repair in: " + file, null, file.getLanguage().getClass()));
PluginException.logPluginError(LOG, "PSI is broken beyond repair in: " + file, null, file.getLanguage().getClass());
}
}
finally {
@@ -19,7 +19,7 @@
*/
package com.intellij.psi.impl.source.tree;
import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.diagnostic.PluginException;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Attachment;
import com.intellij.openapi.diagnostic.LogUtil;
@@ -223,7 +223,7 @@ public class LazyParseableElement extends CompositeElement {
child = child.getTreeNext();
}
if (length != text.length()) {
LOG.error("Text mismatch in " + LogUtil.objectAndClass(getElementType()), PluginManagerCore.createPluginException("Text mismatch", null, getElementType().getClass()),
LOG.error("Text mismatch in " + LogUtil.objectAndClass(getElementType()), PluginException.createByClass("Text mismatch", null, getElementType().getClass()),
new Attachment("code.txt", text.toString()));
}
}
@@ -7,7 +7,6 @@ import com.intellij.codeInsight.daemon.HighlightDisplayKey;
import com.intellij.codeInsight.daemon.impl.analysis.HighlightingLevelManager;
import com.intellij.codeInspection.ex.InspectionProfileImpl;
import com.intellij.diagnostic.PluginException;
import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.lang.ExternalLanguageAnnotators;
import com.intellij.lang.Language;
import com.intellij.lang.annotation.Annotation;
@@ -241,8 +240,7 @@ public class ExternalToolPass extends ProgressableTextEditorHighlightingPass {
String path = file != null ? file.getPath() : root.getName();
final PluginException pluginException =
PluginManagerCore.createPluginException("annotator: " + annotator + " (" + annotator.getClass() + ")",
t, annotator.getClass());
PluginException.createByClass("annotator: " + annotator + " (" + annotator.getClass() + ")", t, annotator.getClass());
LOG.error("ExternalToolPass: ", pluginException, new Attachment("root_path.txt", path));
}
}
@@ -13,7 +13,7 @@ import com.intellij.codeInspection.*;
import com.intellij.codeInspection.ex.*;
import com.intellij.codeInspection.ui.InspectionToolPresentation;
import com.intellij.concurrency.JobLauncher;
import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.diagnostic.PluginException;
import com.intellij.injected.editor.DocumentWindow;
import com.intellij.lang.Language;
import com.intellij.lang.annotation.HighlightSeverity;
@@ -542,7 +542,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
"' (" + tool.getClass() +
") was invoked for. Message: '" + descriptor + "'.\nElement' containing file: " +
context + "\nInspection invoked for file: " + myContext + "\n";
LOG.error(PluginManagerCore.createPluginException(errorMessage, null, tool.getClass()));
PluginException.logPluginError(LOG, errorMessage, null, tool.getClass());
}
boolean isInjected = myInspectInjectedPsi && file != getFile();
if (!isInjected) {
@@ -8,9 +8,9 @@ import com.intellij.codeInsight.TargetElementUtil;
import com.intellij.codeInsight.actions.BaseCodeInsightAction;
import com.intellij.codeInsight.hint.HintManager;
import com.intellij.codeInsight.navigation.NavigationUtil;
import com.intellij.diagnostic.PluginException;
import com.intellij.featureStatistics.FeatureUsageTracker;
import com.intellij.find.actions.ShowUsagesAction;
import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.ide.util.DefaultPsiElementCellRenderer;
import com.intellij.ide.util.EditSourceUtil;
import com.intellij.injected.editor.EditorWindow;
@@ -344,9 +344,9 @@ public class GotoDeclarationAction extends BaseCodeInsightAction implements Code
private static boolean assertNotNullElements(@NotNull PsiElement[] result, Class<?> clazz) {
for (PsiElement element : result) {
if (element == null) {
LOG.error(PluginManagerCore.createPluginException(
PluginException.logPluginError(LOG,
"Null target element is returned by 'getGotoDeclarationTargets' in " + clazz.getName(), null, clazz
));
);
return false;
}
}
@@ -4,6 +4,7 @@ package com.intellij.execution.impl
import com.intellij.configurationStore.SerializableScheme
import com.intellij.configurationStore.deserializeAndLoadState
import com.intellij.configurationStore.serializeStateInto
import com.intellij.diagnostic.PluginException
import com.intellij.execution.ExecutionBundle
import com.intellij.execution.Executor
import com.intellij.execution.ExecutorRegistry
@@ -508,7 +509,7 @@ class RunnerAndConfigurationSettingsImpl @JvmOverloads constructor(val manager:
return settings.getOrPut(runner) { createSettings(runner) }
}
catch (e: AbstractMethodError) {
RunManagerImpl.LOG.error(PluginManagerCore.createPluginException("Update failed for: ${configuration.type.displayName}, runner: ${runner.runnerId}", e, runner.javaClass))
PluginException.logPluginError(RunManagerImpl.LOG, "Update failed for: ${configuration.type.displayName}, runner: ${runner.runnerId}", e, runner.javaClass)
return null
}
}
@@ -2,7 +2,7 @@
package com.intellij.formatting;
import com.intellij.diagnostic.AttachmentFactory;
import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.diagnostic.PluginException;
import com.intellij.lang.Language;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.TextRange;
@@ -55,7 +55,7 @@ class RangesAssert {
buffer.append('\n');
}
Throwable t = problematicLanguageClass != null ? PluginManagerCore.createPluginException("", null, problematicLanguageClass) : null;
Throwable t = problematicLanguageClass != null ? PluginException.createByClass("", null, problematicLanguageClass) : null;
LOG.error(messageBuffer.toString(), t, AttachmentFactory.createContext(buffer));
}
}
@@ -16,7 +16,7 @@
package com.intellij.ide.impl.dataRules;
import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.diagnostic.PluginException;
import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.diagnostic.Logger;
@@ -34,7 +34,7 @@ public class PsiElementFromSelectionsRule implements GetDataRule {
if (!(data instanceof Object[])) {
String errorMessage = "Value for data key 'PlatformDataKeys.SELECTED_ITEMS' must be of type Object[], but " + data.getClass() +
" is returned by " + dataProvider.getClass();
LOG.error(PluginManagerCore.createPluginException(errorMessage, null, dataProvider.getClass()));
PluginException.logPluginError(LOG, errorMessage, null, dataProvider.getClass());
return null;
}
@@ -2,7 +2,7 @@
package com.intellij.ide.util.gotoByName;
import com.intellij.concurrency.JobLauncher;
import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.diagnostic.PluginException;
import com.intellij.ide.util.NavigationItemListCellRenderer;
import com.intellij.navigation.ChooseByNameContributor;
import com.intellij.navigation.ChooseByNameContributorEx;
@@ -191,7 +191,7 @@ public abstract class ContributorsBasedGotoByModel implements ChooseByNameModelE
for (NavigationItem item : itemsByName) {
canceled.checkCanceled();
if (item == null) {
LOG.error(PluginManagerCore.createPluginException("null item from contributor " + contributor + " for name " + name, null, contributor.getClass()));
PluginException.logPluginError(LOG, "null item from contributor " + contributor + " for name " + name, null, contributor.getClass());
continue;
}
@@ -2,7 +2,6 @@
package com.intellij.openapi.module.impl;
import com.intellij.diagnostic.PluginException;
import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.*;
@@ -33,7 +32,7 @@ public class ModuleTypeManagerImpl extends ModuleTypeManager {
public void registerModuleType(ModuleType type, boolean classpathProvider) {
for (ModuleType oldType : myModuleTypes.keySet()) {
if (oldType.getId().equals(type.getId())) {
LOG.error(PluginManagerCore.createPluginException("Trying to register a module type that clashes with existing one. Old=" + oldType + ", new = " + type, null, type.getClass()));
PluginException.logPluginError(LOG, "Trying to register a module type that clashes with existing one. Old=" + oldType + ", new = " + type, null, type.getClass());
return;
}
}
@@ -6,7 +6,7 @@
package com.intellij.openapi.roots.impl;
import com.intellij.ProjectTopics;
import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.diagnostic.PluginException;
import com.intellij.openapi.application.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
@@ -318,7 +318,7 @@ public class PushedFilePropertiesUpdaterImpl extends PushedFilePropertiesUpdater
}
}
catch (AbstractMethodError ame) { // acceptsDirectory is missed
if (pusher != null) throw PluginManagerCore.createPluginException("Failed to apply pusher " + pusher.getClass(), ame, pusher.getClass());
if (pusher != null) throw PluginException.createByClass("Failed to apply pusher " + pusher.getClass(), ame, pusher.getClass());
throw ame;
}
}
@@ -15,7 +15,7 @@
*/
package com.intellij.psi.stubs;
import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.diagnostic.PluginException;
import com.intellij.lang.Language;
import com.intellij.lang.LanguageParserDefinitions;
import com.intellij.lang.ParserDefinition;
@@ -227,8 +227,8 @@ class StubVersionMap {
IStubFileElementType elementType = (IStubFileElementType)owner;
if (elementType.getLanguage() instanceof TemplateLanguage &&
elementType.getStubVersion() < IStubFileElementType.getTemplateStubVersion()) {
LOG.error(PluginManagerCore.createPluginException(elementType.getLanguage() + " stub version should call super.getStubVersion()",
null, elementType.getClass()));
PluginException.logPluginError(LOG, elementType.getLanguage() + " stub version should call super.getStubVersion()",
null, elementType.getClass());
}
return elementType.getStubVersion();
} else {
@@ -2,6 +2,7 @@
package com.intellij.configurationStore
import com.intellij.diagnostic.IdeErrorsDialog
import com.intellij.diagnostic.PluginException
import com.intellij.ide.SaveAndSyncHandler
import com.intellij.ide.SaveAndSyncHandlerImpl
import com.intellij.ide.plugins.PluginManagerCore
@@ -127,7 +128,7 @@ fun <T> getStateSpec(persistentStateComponent: PersistentStateComponent<T>): Sta
fun getStateSpecOrError(componentClass: Class<out PersistentStateComponent<*>>): State {
return getStateSpec(componentClass)
?: throw PluginManagerCore.createPluginException("No @State annotation found in $componentClass", null, componentClass)
?: throw PluginException.createByClass("No @State annotation found in $componentClass", null, componentClass)
}
fun getStateSpec(originalClass: Class<*>): State? {
@@ -352,6 +352,8 @@
<applicationConfigurable parentId="preferences.general" instance="com.intellij.util.net.HttpProxyConfigurable" id="http.proxy" displayName="HTTP Proxy"/>
<applicationConfigurable parentId="preferences.general" instance="com.intellij.ide.gdpr.ConsentConfigurable" id="consents" displayName="Data Sharing"/>
<applicationConfigurable groupId="tools" displayName="Server Certificates" id="http.certificates" instance="com.intellij.util.net.ssl.CertificateConfigurable"/>
<applicationService serviceInterface="com.intellij.diagnostic.PluginProblemReporter"
serviceImplementation="com.intellij.diagnostic.PluginProblemReporterImpl"/>
<fileTypeFactory implementation="com.intellij.openapi.fileTypes.impl.PlatformFileTypeFactory"/>
<fileTypeFactory implementation="com.intellij.openapi.fileTypes.impl.InternalFileTypeFactory"/>
@@ -2,7 +2,7 @@
package com.jetbrains.python.psi.impl;
import com.intellij.codeInsight.controlflow.Instruction;
import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.diagnostic.PluginException;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Ref;
@@ -385,7 +385,7 @@ public class PyReferenceExpressionImpl extends PyElementImpl implements PyRefere
}
}
catch (AbstractMethodError e) {
LOG.info(PluginManagerCore.createPluginException("Failed to get expression type via " + provider.getClass(), e, provider.getClass()));
LOG.info(PluginException.createByClass("Failed to get expression type via " + provider.getClass(), e, provider.getClass()));
}
}
return null;