Made the CommandManager responsible for exception converters as apposed to individual dispatchers

Previously some exceptions were being handled only in the ParametricCallable, which lead to other dispatchers throwing the exception, and requesting that users report them.

Fixes WORLDEDIT-3386
Dieser Commit ist enthalten in:
Wyatt Childers 2016-06-28 19:36:34 -04:00
Ursprung b3d6644972
Commit a091853385
4 geänderte Dateien mit 26 neuen und 84 gelöschten Zeilen

Datei anzeigen

@ -28,41 +28,15 @@ import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.BiomeCommands;
import com.sk89q.worldedit.command.BrushCommands;
import com.sk89q.worldedit.command.ChunkCommands;
import com.sk89q.worldedit.command.ClipboardCommands;
import com.sk89q.worldedit.command.GeneralCommands;
import com.sk89q.worldedit.command.GenerationCommands;
import com.sk89q.worldedit.command.HistoryCommands;
import com.sk89q.worldedit.command.NavigationCommands;
import com.sk89q.worldedit.command.RegionCommands;
import com.sk89q.worldedit.command.SchematicCommands;
import com.sk89q.worldedit.command.ScriptingCommands;
import com.sk89q.worldedit.command.SelectionCommands;
import com.sk89q.worldedit.command.SnapshotCommands;
import com.sk89q.worldedit.command.SnapshotUtilCommands;
import com.sk89q.worldedit.command.SuperPickaxeCommands;
import com.sk89q.worldedit.command.ToolCommands;
import com.sk89q.worldedit.command.ToolUtilCommands;
import com.sk89q.worldedit.command.UtilityCommands;
import com.sk89q.worldedit.command.WorldEditCommands;
import com.sk89q.worldedit.command.*;
import com.sk89q.worldedit.command.argument.ReplaceParser;
import com.sk89q.worldedit.command.argument.TreeGeneratorParser;
import com.sk89q.worldedit.command.composition.ApplyCommand;
import com.sk89q.worldedit.command.composition.DeformCommand;
import com.sk89q.worldedit.command.composition.PaintCommand;
import com.sk89q.worldedit.command.composition.SelectionCommand;
import com.sk89q.worldedit.command.composition.ShapedBrushCommand;
import com.sk89q.worldedit.command.composition.*;
import com.sk89q.worldedit.event.platform.CommandEvent;
import com.sk89q.worldedit.event.platform.CommandSuggestionEvent;
import com.sk89q.worldedit.function.factory.Deform;
import com.sk89q.worldedit.function.factory.Deform.Mode;
import com.sk89q.worldedit.internal.command.ActorAuthorizer;
import com.sk89q.worldedit.internal.command.CommandLoggingHandler;
import com.sk89q.worldedit.internal.command.UserCommandCompleter;
import com.sk89q.worldedit.internal.command.WorldEditBinding;
import com.sk89q.worldedit.internal.command.WorldEditExceptionConverter;
import com.sk89q.worldedit.internal.command.*;
import com.sk89q.worldedit.session.request.Request;
import com.sk89q.worldedit.util.command.Dispatcher;
import com.sk89q.worldedit.util.command.InvalidUsageException;
@ -129,7 +103,6 @@ public final class CommandManager {
builder.setAuthorizer(new ActorAuthorizer());
builder.setDefaultCompleter(new UserCommandCompleter(platformManager));
builder.addBinding(new WorldEditBinding(worldEdit));
builder.addExceptionConverter(exceptionConverter);
builder.addInvokeListener(new LegacyCommandsHandler());
builder.addInvokeListener(new CommandLoggingHandler(worldEdit, commandLog));
@ -267,7 +240,23 @@ public final class CommandManager {
long start = System.currentTimeMillis();
try {
dispatcher.call(Joiner.on(" ").join(split), locals, new String[0]);
// This is a bit of a hack, since the call method can only throw CommandExceptions
// everything needs to be wrapped at least once. Which means to handle all WorldEdit
// exceptions without writing a hook into every dispatcher, we need to unwrap these
// exceptions and rethrow their converted form, if their is one.
try {
dispatcher.call(Joiner.on(" ").join(split), locals, new String[0]);
} catch (Throwable t) {
// Use the exception converter to convert the exception if any of its causes
// can be converted, otherwise throw the original exception
Throwable next = t;
do {
exceptionConverter.convert(next);
next = next.getCause();
} while (next != null);
throw t;
}
} catch (CommandPermissionsException e) {
actor.printError("You are not permitted to do that. Are you in the right mode?");
} catch (InvalidUsageException e) {

Datei anzeigen

@ -68,7 +68,7 @@ public class DispatcherNode {
* @param alias the list of aliases, where the first alias is the primary one
*/
public DispatcherNode register(CommandCallable callable, String... alias) {
dispatcher.registerCommand(callable, alias);;
dispatcher.registerCommand(callable, alias);
return this;
}

Datei anzeigen

@ -57,7 +57,6 @@ public class ParametricBuilder {
private final Map<Type, Binding> bindings = new HashMap<Type, Binding>();
private final Paranamer paranamer = new CachingParanamer();
private final List<InvokeListener> invokeListeners = new ArrayList<InvokeListener>();
private final List<ExceptionConverter> exceptionConverters = new ArrayList<ExceptionConverter>();
private Authorizer authorizer = new NullAuthorizer();
private CommandCompleter defaultCompleter = new NullCompleter();
@ -126,19 +125,6 @@ public class ParametricBuilder {
public void addInvokeListener(InvokeListener listener) {
invokeListeners.add(listener);
}
/**
* Attach an exception converter to this builder in order to wrap unknown
* {@link Throwable}s into known {@link CommandException}s.
*
* <p>Exception converters are called in order that they are registered.</p>
*
* @param converter the converter
* @see ExceptionConverter for an explanation
*/
public void addExceptionConverter(ExceptionConverter converter) {
exceptionConverters.add(converter);
}
/**
* Build a list of commands from methods specially annotated with {@link Command}
@ -201,15 +187,6 @@ public class ParametricBuilder {
return invokeListeners;
}
/**
* Get the list of exception converters.
*
* @return a list of exception converters
*/
List<ExceptionConverter> getExceptionConverters() {
return exceptionConverters;
}
/**
* Get the authorizer.
*

Datei anzeigen

@ -20,30 +20,15 @@
package com.sk89q.worldedit.util.command.parametric;
import com.google.common.primitives.Chars;
import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandLocals;
import com.sk89q.minecraft.util.commands.CommandPermissions;
import com.sk89q.minecraft.util.commands.CommandPermissionsException;
import com.sk89q.minecraft.util.commands.WrappedCommandException;
import com.sk89q.worldedit.util.command.CommandCallable;
import com.sk89q.worldedit.util.command.InvalidUsageException;
import com.sk89q.worldedit.util.command.MissingParameterException;
import com.sk89q.worldedit.util.command.Parameter;
import com.sk89q.worldedit.util.command.SimpleDescription;
import com.sk89q.worldedit.util.command.UnconsumedParameterException;
import com.sk89q.minecraft.util.commands.*;
import com.sk89q.worldedit.util.command.*;
import com.sk89q.worldedit.util.command.binding.Switch;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
/**
* The implementation of a {@link CommandCallable} for the {@link ParametricBuilder}.
@ -255,17 +240,8 @@ class ParametricCallable implements CommandCallable {
String name = parameter.getName();
throw new InvalidUsageException("For parameter '" + name + "': " + e.getMessage(), this);
} catch (InvocationTargetException e) {
for (ExceptionConverter converter : builder.getExceptionConverters()) {
converter.convert(e.getCause());
}
throw new WrappedCommandException(e);
} catch (IllegalArgumentException e) {
throw new WrappedCommandException(e);
} catch (CommandException e) {
throw e;
} catch (Throwable e) {
throw new WrappedCommandException(e);
} catch (Throwable t) {
throw new WrappedCommandException(t);
}
return true;