* #1497 Throw dedicated exception for invalid YAML files and handle it on startup - Wrap SnakeYAML exceptions when loading config.yml and commands.yml on startup into own exception type - Handle exception type on startup with specific error message * #1497 Fix inaccurate JavaDoc comment
This commit is contained in:
@@ -26,11 +26,13 @@ import fr.xephi.authme.service.BackupService;
|
||||
import fr.xephi.authme.service.BukkitService;
|
||||
import fr.xephi.authme.service.MigrationService;
|
||||
import fr.xephi.authme.service.bungeecord.BungeeReceiver;
|
||||
import fr.xephi.authme.service.yaml.YamlParseException;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.SettingsWarner;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import fr.xephi.authme.task.CleanupTask;
|
||||
import fr.xephi.authme.task.purge.PurgeService;
|
||||
import fr.xephi.authme.util.ExceptionUtils;
|
||||
import org.apache.commons.lang.SystemUtils;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.command.Command;
|
||||
@@ -133,7 +135,13 @@ public class AuthMe extends JavaPlugin {
|
||||
try {
|
||||
initialize();
|
||||
} catch (Throwable th) {
|
||||
ConsoleLogger.logException("Aborting initialization of AuthMe:", th);
|
||||
YamlParseException yamlParseException = ExceptionUtils.findThrowableInCause(YamlParseException.class, th);
|
||||
if (yamlParseException == null) {
|
||||
ConsoleLogger.logException("Aborting initialization of AuthMe:", th);
|
||||
} else {
|
||||
ConsoleLogger.logException("File '" + yamlParseException.getFile() + "' contains invalid YAML. "
|
||||
+ "Please run its contents through http://yamllint.com", yamlParseException);
|
||||
}
|
||||
stopOrUnload();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package fr.xephi.authme.initialization;
|
||||
|
||||
import ch.jalu.configme.configurationdata.ConfigurationData;
|
||||
import ch.jalu.configme.resource.PropertyResource;
|
||||
import ch.jalu.configme.resource.YamlFileResource;
|
||||
import fr.xephi.authme.service.yaml.YamlFileResourceProvider;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.SettingsMigrationService;
|
||||
import fr.xephi.authme.settings.properties.AuthMeSettingsRetriever;
|
||||
@@ -37,7 +37,7 @@ public class SettingsProvider implements Provider<Settings> {
|
||||
if (!configFile.exists()) {
|
||||
FileUtils.create(configFile);
|
||||
}
|
||||
PropertyResource resource = new YamlFileResource(configFile);
|
||||
PropertyResource resource = YamlFileResourceProvider.loadFromFile(configFile);
|
||||
ConfigurationData configurationData = AuthMeSettingsRetriever.buildConfigurationData();
|
||||
return new Settings(dataFolder, resource, migrationService, configurationData);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package fr.xephi.authme.service.yaml;
|
||||
|
||||
import ch.jalu.configme.resource.YamlFileResource;
|
||||
import org.yaml.snakeyaml.parser.ParserException;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Creates {@link YamlFileResource} objects.
|
||||
*/
|
||||
public final class YamlFileResourceProvider {
|
||||
|
||||
private YamlFileResourceProvider() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link YamlFileResource} instance for the given file. Wraps SnakeYAML's parse exception
|
||||
* into an AuthMe exception.
|
||||
*
|
||||
* @param file the file to load
|
||||
* @return the generated resource
|
||||
*/
|
||||
public static YamlFileResource loadFromFile(File file) {
|
||||
try {
|
||||
return new YamlFileResource(file);
|
||||
} catch (ParserException e) {
|
||||
throw new YamlParseException(file.getPath(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package fr.xephi.authme.service.yaml;
|
||||
|
||||
import org.yaml.snakeyaml.parser.ParserException;
|
||||
|
||||
/**
|
||||
* Exception when a YAML file could not be parsed.
|
||||
*/
|
||||
public class YamlParseException extends RuntimeException {
|
||||
|
||||
private final String file;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param file the file a parsing exception occurred with
|
||||
* @param snakeYamlException the caught exception from SnakeYAML
|
||||
*/
|
||||
public YamlParseException(String file, ParserException snakeYamlException) {
|
||||
super(snakeYamlException);
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
public String getFile() {
|
||||
return file;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
package fr.xephi.authme.settings.commandconfig;
|
||||
|
||||
import ch.jalu.configme.SettingsManager;
|
||||
import ch.jalu.configme.resource.YamlFileResource;
|
||||
import fr.xephi.authme.initialization.DataFolder;
|
||||
import fr.xephi.authme.initialization.Reloadable;
|
||||
import fr.xephi.authme.service.BukkitService;
|
||||
import fr.xephi.authme.service.GeoIpService;
|
||||
import fr.xephi.authme.service.yaml.YamlFileResourceProvider;
|
||||
import fr.xephi.authme.util.FileUtils;
|
||||
import fr.xephi.authme.util.PlayerUtils;
|
||||
import fr.xephi.authme.util.lazytags.Tag;
|
||||
@@ -149,7 +149,7 @@ public class CommandManager implements Reloadable {
|
||||
FileUtils.copyFileFromResource(file, "commands.yml");
|
||||
|
||||
SettingsManager settingsManager = new SettingsManager(
|
||||
new YamlFileResource(file), commandMigrationService, CommandSettingsHolder.class);
|
||||
YamlFileResourceProvider.loadFromFile(file), commandMigrationService, CommandSettingsHolder.class);
|
||||
CommandConfig commandConfig = settingsManager.getProperty(CommandSettingsHolder.COMMANDS);
|
||||
onJoinCommands = newReplacer(commandConfig.getOnJoin());
|
||||
onLoginCommands = newOnLoginCmdReplacer(commandConfig.getOnLogin());
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package fr.xephi.authme.util;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Utilities for exceptions.
|
||||
*/
|
||||
public final class ExceptionUtils {
|
||||
|
||||
private ExceptionUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first throwable of the given {@code wantedThrowableType} by visiting the provided
|
||||
* throwable and its causes recursively.
|
||||
*
|
||||
* @param wantedThrowableType the throwable type to find
|
||||
* @param throwable the throwable to start with
|
||||
* @param <T> the desired throwable subtype
|
||||
* @return the first throwable found of the given type, or null if none found
|
||||
*/
|
||||
public static <T extends Throwable> T findThrowableInCause(Class<T> wantedThrowableType, Throwable throwable) {
|
||||
Set<Throwable> visitedObjects = Sets.newIdentityHashSet();
|
||||
Throwable currentThrowable = throwable;
|
||||
while (currentThrowable != null && !visitedObjects.contains(currentThrowable)) {
|
||||
if (wantedThrowableType.isInstance(currentThrowable)) {
|
||||
return wantedThrowableType.cast(currentThrowable);
|
||||
}
|
||||
visitedObjects.add(currentThrowable);
|
||||
currentThrowable = currentThrowable.getCause();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user