Improved Extension error cases

- Extensions can now be disabled even when the creation fails
- Extension creation error stack traces are pruned better

Affects issues:
- #1248, #1246
This commit is contained in:
Rsl1122 2019-12-16 15:22:26 +02:00
parent a7baf157d8
commit 4611c327d4
3 changed files with 37 additions and 5 deletions

View File

@ -86,8 +86,8 @@ public class ExtensionServiceImplementation implements ExtensionService {
try {
extensionRegister.registerBuiltInExtensions(config.getExtensionSettings().getDisabled());
} catch (IllegalStateException failedToRegisterOne) {
logger.warn("One or more extensions failed to register, see suppressed exceptions.");
errorHandler.log(L.WARN, this.getClass(), failedToRegisterOne);
logger.warn("One or more extensions failed to register, see suppressed exceptions (They can be disabled in Plan config).");
errorHandler.log(L.WARN, ExtensionService.class, failedToRegisterOne);
}
}

View File

@ -23,7 +23,9 @@ import com.djrapitops.plan.settings.locale.LocaleSystem;
import dagger.Module;
import dagger.Provides;
import javax.inject.Named;
import javax.inject.Singleton;
import java.util.function.Function;
/**
* Module for binding object instances found inside other systems.
@ -45,4 +47,11 @@ public class SystemObjectProvidingModule {
return config.getExtensionSettings();
}
@Provides
@Singleton
@Named("isExtensionEnabled")
Function<String, Boolean> provideExtensionEnabledConfigCheck(PlanConfig config) {
return config.getExtensionSettings()::isEnabled;
}
}

View File

@ -24,6 +24,7 @@ import com.djrapitops.plan.extension.NotReadyException;
import com.djrapitops.plan.extension.extractor.ExtensionExtractor;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import java.util.Optional;
import java.util.Set;
@ -38,13 +39,15 @@ import java.util.function.Function;
@Singleton
public class ExtensionRegister {
private final Function<String, Boolean> isExtensionEnabledInConfig;
private IllegalStateException registerException;
private Set<String> disabledExtensions;
private ExtensionService extensionService;
@Inject
public ExtensionRegister() {
public ExtensionRegister(@Named("isExtensionEnabled") Function<String, Boolean> isExtensionEnabledInConfig) {
/* Required for dagger injection */
this.isExtensionEnabledInConfig = isExtensionEnabledInConfig;
}
public void registerBuiltInExtensions(Set<String> disabledExtensions) {
@ -92,16 +95,36 @@ public class ExtensionRegister {
}
private void suppressException(Class factory, Throwable e) {
String factoryName = factory.getSimpleName();
String extensionName = factoryName.replace("ExtensionFactory", "");
if (!isExtensionEnabledInConfig.apply(extensionName)) {
return;
}
// Places all exceptions to one exception with plugin information so that they can be reported.
if (registerException == null) {
registerException = new IllegalStateException("One or more extensions failed to register:");
registerException.setStackTrace(new StackTraceElement[0]);
}
IllegalStateException info = new IllegalStateException(factory.getSimpleName() + " ran into exception when creating Extension", e);
info.setStackTrace(new StackTraceElement[0]);
IllegalStateException info = new IllegalStateException(factoryName + " failed to create Extension", e);
removeUselessStackTraces(info);
registerException.addSuppressed(info);
}
private void removeUselessStackTraces(Throwable t) {
if (t == null) return;
if (t instanceof ReflectiveOperationException
|| t instanceof NoClassDefFoundError
|| t instanceof NoSuchFieldError
|| t instanceof NoSuchMethodError
|| t instanceof IllegalStateException
) {
t.setStackTrace(new StackTraceElement[0]);
}
removeUselessStackTraces(t.getCause());
}
private <T> void register(
T factory,
Function<T, Optional<DataExtension>> createExtension