User Tools

Site Tools


zh_cn:tutorial:command_exceptions

命令异常

Brigadier 支持命令异常,这些异常可用于结束命令,例如参数未正确解析或命令未能执行,以及更丰富的错误细节。

命令异常有以下两种类型:

  • CommandSyntaxException:由 Brigadier 提供,需要先有一个异常类型,然后通过 create(…)createWithContext(…) 创建。不属于 RuntimeException,所以一旦抛出,必须被适当捕获,或者添加到方法签名中。
  • CommandException(自 1.20.3 被移除):由 Minecraft 提供,用于更少的情况。属于 RuntimeException,可以直接传入 Text 作为参数。

CommandSyntaxException 的两种类型包括动态和基本的类型,其中你可以调用 create() 以创建一个异常以抛出。这些异常也允许你指定环境,使用 createWithContext(ImmutableStringReader) 就可以,会构建出一条异常消息以指出你输入的命令中哪里出现错误。

下面是一个抛硬币的代码,用于显示使用中的异常示例。

使用 CommandException

  1. dispatcher.register(literal("coinflip")
  2. .executes(ctx -> {
  3. Random random = ctx.getSource().getWorld().getRandom();
  4.  
  5. if(random.nextBoolean()) { // 如果是正面。
  6. ctx.getSource().sendFeedback(() -> Text.translatable("coin.flip.heads"), true);
  7. return Command.SINGLE_SUCCESS;
  8. }
  9.  
  10. throw new CommandException(Text.translatable("coin.flip.tails"));
  11. }));

:!: CommandException is removed since 1.20.3.

使用 CommandSyntaxException

如果你使用 CommandSyntaxException,需要先添加一个 SimpleCommandExceptionType,通常存储为字段,所以这个例子呈现一整个类。

public class ExampleMod implements ModInitializer {
  public static final SimpleCommandExceptionType COIN_FLIP_TAILS = new SimpleCommandExceptionType(Text.translatable("coin.flip.tails"));
  @Override
  public void onInitialize() {
    CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> dispatcher.register(literal("coinflip")
        .executes(ctx -> {
          Random random = ctx.getSource().getWorld().getRandom();
 
          if (random.nextBoolean()) { // 如果是正面。
            ctx.getSource().sendFeedback(() -> Text.translatable("coin.flip.heads"), true);
            return Command.SINGLE_SUCCESS;
          }
 
          throw COIN_FLIP_TAILS.create();
        })));
  }
}

有时你也会使用 DynamicCommandExceptionType 以接受复杂的异常,例如:

public class ExampleMod implements ModInitializer {
  public static final DynamicCommandExceptionType COIN_FLIP_TAILS = new DynamicCommandExceptionType(o -> Text.translatable("coin.flip.tails", o));
 
  @Override
  public void onInitialize() {
    CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> dispatcher.register(literal("coinflip")
        .executes(ctx -> {
          Random random = ctx.getSource().getWorld().getRandom();
 
          if (random.nextBoolean()) { // 如果是正面。
            ctx.getSource().sendFeedback(() -> Text.translatable("coin.flip.heads"), true);
            return Command.SINGLE_SUCCESS;
          }
 
          throw COIN_FLIP_TAILS.create(ctx.getSource().getDisplayName());
        })));
  }
}

有更多的动态异常类型,可以接受不同数量的参数(Dynamic2CommandExceptionTypeDynamic3CommandExceptionTypeDynamic4CommandExceptionTypeDynamicNCommandExceptionType)。请记住,动态异常会接收 object 作为参数,因此你在使用时可能需要强转。

有些原版的异常,可以见于 CommandSyntaxException.BUILT_IN_EXCEPTIONS.<异常类型>()

zh_cn/tutorial/command_exceptions.txt · Last modified: 2024/04/15 06:35 by solidblock