Problem Description
A user of my plugin encountered an exception in PhpStorm, preventing the JSON editor provider from loading. The error indicates a timeout (TimeoutCancellationException) during provider initialization, but the root cause is unclear. Seeking community assistance to diagnose the issue.
Environment Details
IDE: PhpStorm 2024.3.5 (Build #PS-243.26053.13)
OS: macOS (exact version unspecified; user should confirm)
Java Version: OpenJDK 64-Bit Server VM 21.0.6+8-b631.39
Reproducibility: Confirmed in PhpStorm. Untested in other JetBrains IDEs (user to verify).
Full Exception Stack
com.intellij.diagnostic.PluginException: Cannot check provider cn.memoryzy.json.extension.provider.JsonFileEditorProvider [Plugin: cn.memoryzy.json]
at com.intellij.openapi.fileEditor.impl.FileEditorProviderManagerImpl$getProviders$sharedProviders$1$1$1.invokeSuspend(FileEditorProviderManagerImpl.kt:157)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.internal.ScopeCoroutine.afterResume(Scopes.kt:29)
at kotlinx.coroutines.AbstractCoroutine.resumeWith(AbstractCoroutine.kt:99)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46)
at kotlinx.coroutines.UndispatchedCoroutine.afterResume(CoroutineContext.kt:277)
at kotlinx.coroutines.AbstractCoroutine.resumeWith(AbstractCoroutine.kt:99)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:234)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:608)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:873)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:763)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:750)
Caused by: kotlinx.coroutines.TimeoutCancellationException: Timed out waiting for 30000 ms
at kotlinx.coroutines.TimeoutKt.TimeoutCancellationException(Timeout.kt:188)
at kotlinx.coroutines.TimeoutCoroutine.run(Timeout.kt:156)
at kotlinx.coroutines.EventLoopImplBase$DelayedRunnableTask.run(EventLoop.common.kt:498)
at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:277)
at kotlinx.coroutines.DefaultExecutor.run(DefaultExecutor.kt:105)
at java.base/java.lang.Thread.run(Thread.java:1583)
Here is my code implementation:
FileEditorProvider:
public class JsonTreeFileEditorProvider implements FileEditorProvider {
@Override
public boolean accept(@NotNull Project project, @NotNull VirtualFile file) {
return PlatformUtil.isJsonFileType(file.getFileType());
}
@Override
public @NotNull FileEditor createEditor(@NotNull Project project, @NotNull VirtualFile file) {
return new JsonTreeFileEditor(project, file);
}
@Override
public @NotNull @NonNls String getEditorTypeId() {
return JsonAssistantPlugin.PLUGIN_ID_NAME + ".JsonTreeFileEditor";
}
@Override
public @NotNull FileEditorPolicy getPolicy() {
return FileEditorPolicy.PLACE_AFTER_DEFAULT_EDITOR;
}
}
FileEditor:
public class JsonTreeFileEditor extends UserDataHolderBase implements FileEditor {
private final Project project;
private final VirtualFile file;
private final JsonTreeEditorComponentProvider provider;
public JsonTreeFileEditor(Project project, VirtualFile file) {
this.project = project;
this.file = file;
this.provider = new JsonTreeEditorComponentProvider(project, file);
}
@Override
public @NotNull JComponent getComponent() {
return provider.getComponent();
}
@Override
public @Nullable JComponent getPreferredFocusedComponent() {
return provider.getPreferredFocusedComponent();
}
@Override
public @Nls(capitalization = Nls.Capitalization.Title) @NotNull String getName() {
return "Structure";
}
@Override
public void setState(@NotNull FileEditorState state) {
}
@Override
public @NotNull FileEditorState getState(@NotNull FileEditorStateLevel level) {
return FileEditor.super.getState(level);
}
@Override
public boolean isModified() {
return false;
}
@Override
public boolean isValid() {
return true;
}
@Override
public VirtualFile getFile() {
return file;
}
@Override
public void addPropertyChangeListener(@NotNull PropertyChangeListener listener) {
}
@Override
public void removePropertyChangeListener(@NotNull PropertyChangeListener listener) {
}
@Override
public void selectNotify() {
provider.compareAndRefresh(project, file);
}
@Override
public @Nullable FileEditorLocation getCurrentLocation() {
return null;
}
@Override
public void dispose() {
}
}