diff --git a/docs/scarpet/language/FunctionsAndControlFlow.md b/docs/scarpet/language/FunctionsAndControlFlow.md index f44ffcbc..28a03fb0 100644 --- a/docs/scarpet/language/FunctionsAndControlFlow.md +++ b/docs/scarpet/language/FunctionsAndControlFlow.md @@ -237,39 +237,50 @@ It terminates entire program passing `expr` as the result of the program executi ### `try(expr, id_filter?, catch_expr(_, _msg)?)` `try` function evaluates expression, and continues further unless an exception is thrown anywhere inside `expr`, -it being produced by `throw` or a catchable exception is thrown by Carpet. In that case the `catch_expr` is evaluated with -`_` set to the id of the exception and `_msg` set to the exception message. If `id_filter` is present, only exceptions -with an id equal to that value will be catched, and any other exception will continue up the stack. It is recommended to filter +it being produced by `throw` or a catchable exception being thrown by Carpet. In that case the `catch_expr` is evaluated with +`_` set to the id of the exception and `_msg` set to the exception message. If an `id_filter` is present, only exceptions +with an id equal to that value will be caught, and any other exception will continue up the stack. It is recommended to filter the exceptions to catch to be able to distinguish from an exception that is known that may happen from one that shouldn't. This mechanic accepts skipping catch expression - then try returns `null`. This mechanism allows to terminate large -portion of a convoluted call stack and continue program execution. There is only one level of exceptions currently in carpet, -so if the inner function also defines the `try` catchment area, it will received the exception first, but it can technically -rethrow the value its getting for the outer scope. +portion of a convoluted call stack and continue program execution. + +A `try` block will not only catch any exception whose id match the `id_filter`, but also any exception that has a parent with +their id being that one, recursively. The `try` function allows you to catch some Scarpet exceptions for those cases when trying to get things like items, -blocks, biomes or dimensions from registries, that may have been modified by resourcepacks or mods, or when an error that -is out of the scope of the programmer occurs, like problems when reading a file. +blocks, biomes or dimensions from registries, that may have been modified by datapacks, resourcepacks or other mods, or when an error that +is out of the scope of the programmer occurs, such as problems when reading files. -In this documentation, those are documented in at least most of the functions that throw them, and the current list of exceptions -is the following: -- `unknown_item`: Happens when a specified item doesn't exist -- `unknown_block`: Happens when a specified block doesn't exist -- `unknown_biome`: Happens when a specified biome doesn't exist -- `unknown_sound`: Happens when a specified sound doesn't exist -- `unknown_particle`: Happens when a specified particle doesn't exist -- `unknown_poi_type`: Happens when a specified POI type doesn't exist -- `unknown_dimension`: Happens when a specified dimension doesn't exist -- `unknown_structure`: Happens when a specified structure doesn't exist -- `unknown_criterion`: Happens when a specified scoreboard criterion doesn't exist -- `nbt_read_exception`: Happens when there is an exception while reading an NBT file -- `json_read_exception`: Happens when there is an exception while reading a JSON file +In this documentation, those are documented in at least most of the functions that throw them, and the current exception +hierarchy is the following: +- `exception`: This is the base exception. Every exception has this as its top-level parent + - `value_exception`: This is the parent for any exception that occurs due to a provided value for something not being present in the game + - `unknown_item`: Happens when a specified item doesn't exist + - `unknown_block`: Happens when a specified block doesn't exist + - `unknown_biome`: Happens when a specified biome doesn't exist + - `unknown_sound`: Happens when a specified sound doesn't exist + - `unknown_particle`: Happens when a specified particle doesn't exist + - `unknown_poi_type`: Happens when a specified POI type doesn't exist + - `unknown_dimension`: Happens when a specified dimension doesn't exist + - `unknown_structure`: Happens when a specified structure doesn't exist + - `unknown_criterion`: Happens when a specified scoreboard criterion doesn't exist + - `file_read_exception`: This is the parent for any exception that occurs due to an error while reading a file, including appdata load + - `nbt_read_exception`: Happens when there is an exception while reading an NBT file + - `json_read_exception`: Happens when there is an exception while reading a JSON file + - `user_defined_exception`: This is the parent for any exception thrown by the below `throw` function, except for those that explicitly declare + their parent to be one of the above -### `throw(id?, message?)` +### `throw(id?, message?, parent?)` -Throws an exception that can be catched in a `try` block (see above). If ran without arguments, it will pass `null` +Throws an exception that can be caught in a `try` block (see above). If ran without arguments, it will pass `null` as the value to the `catch_expr`. `message` is the message to show to chat or console in case the `throw` is unhandled. +By default, the parent of any exception thrown by this function is `user_defined_exception`. +You can specify the `parent` to be either an already existing exception from the list above, in which case your exception +will not inherit from `user_defined_exception`, or specify a custom one, in which case your exception will inherit from +`exception` > `user_defined_exception` > `parent` > `id` + ### `if(cond, expr, cond?, expr?, ..., default?)` If statement is a function that takes a number of conditions that are evaluated one after another and if any of diff --git a/src/main/java/carpet/script/api/Auxiliary.java b/src/main/java/carpet/script/api/Auxiliary.java index 74d152fe..df5bb8df 100644 --- a/src/main/java/carpet/script/api/Auxiliary.java +++ b/src/main/java/carpet/script/api/Auxiliary.java @@ -20,6 +20,7 @@ import carpet.script.argument.Vector3Argument; import carpet.script.exception.ExitStatement; import carpet.script.exception.InternalExpressionException; import carpet.script.exception.ThrowStatement; +import carpet.script.exception.Throwables; import carpet.script.utils.FixedCommandSource; import carpet.script.utils.ScarpetJsonDeserializer; import carpet.script.utils.ShapeDispatcher; @@ -132,7 +133,7 @@ public class Auxiliary { Identifier soundName = new Identifier(lv.get(0).evalValue(c).getString()); Vector3Argument locator = Vector3Argument.findIn(cc, lv, 1); if (Registry.SOUND_EVENT.get(soundName) == null) - throw new ThrowStatement("No such sound: "+soundName.getPath(), ThrowStatement.UNKNOWN_SOUND); + throw new ThrowStatement("No such sound: "+soundName.getPath(), Throwables.UNKNOWN_SOUND); float volume = 1.0F; float pitch = 1.0F; SoundCategory mixer = SoundCategory.MASTER; @@ -828,7 +829,7 @@ public class Auxiliary { state = ((CarpetScriptHost) c.host).readFileTag(fdesc.getLeft(), fdesc.getRight()); } catch (CrashException e) { - throw new ThrowStatement("Couldn't read NBT data", ThrowStatement.NBT_READ_EXCEPTION); + throw new ThrowStatement("Couldn't read NBT data", Throwables.NBT_READ); } if (state == null) return LazyValue.NULL; @@ -846,7 +847,7 @@ public class Auxiliary { Throwable exc = e; if(e.getCause() != null) exc = e.getCause(); - throw new ThrowStatement("Failed to read JSON file: "+exc.getMessage(), ThrowStatement.JSON_READ_EXCEPTION); + throw new ThrowStatement("Failed to read JSON file: "+exc.getMessage(), Throwables.JSON_READ); } Value parsedJson = gson.fromJson(json, Value.class); if (parsedJson == null) @@ -940,7 +941,7 @@ public class Auxiliary { state = ((CarpetScriptHost)((CarpetContext)c).host).readFileTag(file, shared); } catch (CrashException e) { - throw new ThrowStatement("Failed to read App data", ThrowStatement.NBT_READ_EXCEPTION); + throw new ThrowStatement("Failed to read App data", Throwables.NBT_READ); } if (state == null) return (cc, tt) -> Value.NULL; diff --git a/src/main/java/carpet/script/api/Inventories.java b/src/main/java/carpet/script/api/Inventories.java index 713b7ac2..01fa4ea8 100644 --- a/src/main/java/carpet/script/api/Inventories.java +++ b/src/main/java/carpet/script/api/Inventories.java @@ -7,6 +7,7 @@ import carpet.script.Expression; import carpet.script.LazyValue; import carpet.script.exception.InternalExpressionException; import carpet.script.exception.ThrowStatement; +import carpet.script.exception.Throwables; import carpet.script.value.ListValue; import carpet.script.value.NBTSerializableValue; import carpet.script.value.NullValue; @@ -192,7 +193,7 @@ public class Inventories { String itemStr = lv.get(0).evalValue(c).getString(); Item item; Identifier id = new Identifier(itemStr); - item = Registry.ITEM.getOrEmpty(id).orElseThrow(() -> new ThrowStatement("Incorrect item: "+itemStr, ThrowStatement.UNKNOWN_ITEM)); + item = Registry.ITEM.getOrEmpty(id).orElseThrow(() -> new ThrowStatement("Incorrect item: "+itemStr, Throwables.UNKNOWN_ITEM)); if (!item.hasRecipeRemainder()) return LazyValue.NULL; Value ret = new StringValue(NBTSerializableValue.nameFromRegistryId(Registry.ITEM.getId(item.getRecipeRemainder()))); diff --git a/src/main/java/carpet/script/api/Scoreboards.java b/src/main/java/carpet/script/api/Scoreboards.java index 73097127..c58f7c10 100644 --- a/src/main/java/carpet/script/api/Scoreboards.java +++ b/src/main/java/carpet/script/api/Scoreboards.java @@ -7,6 +7,7 @@ import carpet.script.Expression; import carpet.script.LazyValue; import carpet.script.exception.InternalExpressionException; import carpet.script.exception.ThrowStatement; +import carpet.script.exception.Throwables; import carpet.script.value.EntityValue; import carpet.script.value.ListValue; import carpet.script.value.NullValue; @@ -132,7 +133,7 @@ public class Scoreboards { criterion = ScoreboardCriterion.createStatCriterion(critetionName).orElse(null); if (criterion==null) { - throw new ThrowStatement("Unknown scoreboard criterion: "+critetionName, ThrowStatement.UNKNOWN_CRITERION); + throw new ThrowStatement("Unknown scoreboard criterion: "+critetionName, Throwables.UNKNOWN_CRITERION); } } diff --git a/src/main/java/carpet/script/api/WorldAccess.java b/src/main/java/carpet/script/api/WorldAccess.java index eee5ecd4..85367839 100644 --- a/src/main/java/carpet/script/api/WorldAccess.java +++ b/src/main/java/carpet/script/api/WorldAccess.java @@ -20,6 +20,7 @@ import carpet.script.argument.BlockArgument; import carpet.script.argument.Vector3Argument; import carpet.script.exception.InternalExpressionException; import carpet.script.exception.ThrowStatement; +import carpet.script.exception.Throwables; import carpet.script.utils.BiomeInfo; import carpet.script.utils.WorldTools; import carpet.script.value.BlockValue; @@ -338,7 +339,7 @@ public class WorldAccess { if (!"any".equals(poiType)) { PointOfInterestType type = Registry.POINT_OF_INTEREST_TYPE.getOrEmpty(new Identifier(poiType)) - .orElseThrow(() -> new ThrowStatement("Unknown POI type", ThrowStatement.UNKNOWN_POI_TYPE)); + .orElseThrow(() -> new ThrowStatement("Unknown POI type", Throwables.UNKNOWN_POI_TYPE)); condition = (tt) -> tt == type; } if (locator.offset + 2 < lv.size()) @@ -393,7 +394,7 @@ public class WorldAccess { } String poiTypeString = poi.getString().toLowerCase(Locale.ROOT); PointOfInterestType type = Registry.POINT_OF_INTEREST_TYPE.getOrEmpty(new Identifier(poiTypeString)) - .orElseThrow(() -> new ThrowStatement("Unknown POI type: "+poiTypeString, ThrowStatement.UNKNOWN_POI_TYPE)); + .orElseThrow(() -> new ThrowStatement("Unknown POI type: "+poiTypeString, Throwables.UNKNOWN_POI_TYPE)); int occupancy = 0; if (locator.offset + 1 < lv.size()) { @@ -873,7 +874,7 @@ public class WorldAccess { playerBreak = true; String itemString = val.getString(); item = Registry.ITEM.getOrEmpty(new Identifier(itemString)) - .orElseThrow(() -> new ThrowStatement("Incorrect item: " + itemString, ThrowStatement.UNKNOWN_ITEM)); + .orElseThrow(() -> new ThrowStatement("Incorrect item: " + itemString, Throwables.UNKNOWN_ITEM)); } } CompoundTag tag = null; @@ -1180,7 +1181,7 @@ public class WorldAccess { String biomeName = lv.get(locator.offset+0).evalValue(c).getString(); // from locatebiome command code Biome biome = cc.s.getMinecraftServer().getRegistryManager().get(Registry.BIOME_KEY).getOrEmpty(new Identifier(biomeName)) - .orElseThrow(() -> new ThrowStatement("Unknown biome: "+biomeName, ThrowStatement.UNKNOWN_BIOME)); + .orElseThrow(() -> new ThrowStatement("Unknown biome: "+biomeName, Throwables.UNKNOWN_BIOME)); boolean doImmediateUpdate = true; if (lv.size() > locator.offset+1) { @@ -1250,7 +1251,7 @@ public class WorldAccess { { String reqString = requested.getString(); structure = Registry.STRUCTURE_FEATURE.getOrEmpty(new Identifier(reqString)) - .orElseThrow(() -> new ThrowStatement("Unknown structure: " + reqString, ThrowStatement.UNKNOWN_STRUCTURE)); + .orElseThrow(() -> new ThrowStatement("Unknown structure: " + reqString, Throwables.UNKNOWN_STRUCTURE)); } if (lv.size() > locator.offset+1) { @@ -1330,7 +1331,7 @@ public class WorldAccess { throw new InternalExpressionException("'set_structure requires at least position and a structure name"); String structureName = lv.get(locator.offset).evalValue(c).getString().toLowerCase(Locale.ROOT); ConfiguredStructureFeature configuredStructure = FeatureGenerator.resolveConfiguredStructure(structureName, world, pos); - if (configuredStructure == null) throw new ThrowStatement("Unknown structure: "+structureName, ThrowStatement.UNKNOWN_STRUCTURE); + if (configuredStructure == null) throw new ThrowStatement("Unknown structure: "+structureName, Throwables.UNKNOWN_STRUCTURE); // good 'ol pointer Value[] result = new Value[]{Value.NULL}; // technically a world modification. Even if we could let it slide, we will still park it diff --git a/src/main/java/carpet/script/exception/ProcessedThrowStatement.java b/src/main/java/carpet/script/exception/ProcessedThrowStatement.java index 9e5a9983..003b71b0 100644 --- a/src/main/java/carpet/script/exception/ProcessedThrowStatement.java +++ b/src/main/java/carpet/script/exception/ProcessedThrowStatement.java @@ -6,15 +6,14 @@ import carpet.script.Context; import carpet.script.Expression; import carpet.script.Tokenizer.Token; import carpet.script.value.FunctionValue; -import carpet.script.value.Value; public class ProcessedThrowStatement extends ExpressionException { - public final Value exceptionName; + public final Throwables.Exception exception; public final String message; - public ProcessedThrowStatement(Context c, Expression e, Token token, String message, List stack, Value exceptionName) { + public ProcessedThrowStatement(Context c, Expression e, Token token, String message, List stack, Throwables.Exception exception) { super(c, e, token, "Unhandled exception: "+message, stack); - this.exceptionName = exceptionName; + this.exception = exception; this.message = message; } } diff --git a/src/main/java/carpet/script/exception/ThrowStatement.java b/src/main/java/carpet/script/exception/ThrowStatement.java index db32a335..b8cb4155 100644 --- a/src/main/java/carpet/script/exception/ThrowStatement.java +++ b/src/main/java/carpet/script/exception/ThrowStatement.java @@ -3,47 +3,35 @@ package carpet.script.exception; import carpet.script.Context; import carpet.script.Expression; import carpet.script.Tokenizer.Token; -import carpet.script.value.StringValue; import carpet.script.value.Value; +import static carpet.script.exception.Throwables.Exception; + public class ThrowStatement extends InternalExpressionException { - public static final String UNKNOWN_ITEM = "unknown_item"; - public static final String UNKNOWN_BLOCK = "unknown_block"; - public static final String UNKNOWN_BIOME = "unknown_biome"; - public static final String UNKNOWN_SOUND = "unknown_sound"; - public static final String UNKNOWN_PARTICLE = "unknown_particle"; - public static final String UNKNOWN_POI_TYPE = "unknown_poi_type"; - public static final String UNKNOWN_DIMENSION = "unknown_dimension"; - public static final String UNKNOWN_STRUCTURE = "unknown_structure"; - public static final String UNKNOWN_CRITERION = "unknown_criterion"; - public static final String NBT_READ_EXCEPTION = "nbt_read_exception"; - public static final String JSON_READ_EXCEPTION = "json_read_exception"; - public final Value retval; + private final Exception exception; /** * Creates a throw exception from a value. * That value will also be used as the message.
- * To use when throwing from Scarpet's {@code throw} + * To be used when throwing from Scarpet's {@code throw} function with a single argument * @param value The value to pass */ public ThrowStatement(Value value) { - super(value.getString()); - retval = value; + this(value, value, Value.NULL); } /** - * Creates a throw exception from a value, and - * assigns it a specified message.
- * To use when throwing from Scarpet's {@code throw} - * function + * Creates a throw exception from a value, and assigns it a specified message. + *

To be used when throwing from Scarpet's {@code throw} function * @param message The message to display if uncaught * @param value The value to pass + * @param parent A parent's name */ - public ThrowStatement(String message, Value value) + public ThrowStatement(Value message, Value value, Value parent) { - super(message); - retval = value; + super(message.getString()); + exception = new Exception(value, parent); } /** @@ -54,15 +42,16 @@ public class ThrowStatement extends InternalExpressionException * @param value A String that will be converted * to a value to pass to {@code catch} * blocks + * @param parent This exception's data */ - public ThrowStatement(String message, String value) + public ThrowStatement(String message, Exception exception) { super(message); - retval = new StringValue(value); + this.exception = exception; } @Override public ExpressionException promote(Context c, Expression e, Token token) { - return new ProcessedThrowStatement(c, e, token, getMessage(), stack, retval); + return new ProcessedThrowStatement(c, e, token, getMessage(), stack, exception); } } diff --git a/src/main/java/carpet/script/exception/Throwables.java b/src/main/java/carpet/script/exception/Throwables.java new file mode 100644 index 00000000..4bdfeebe --- /dev/null +++ b/src/main/java/carpet/script/exception/Throwables.java @@ -0,0 +1,127 @@ +package carpet.script.exception; + +import java.util.HashMap; +import java.util.Map; + +import carpet.script.value.NullValue; +import carpet.script.value.StringValue; +import carpet.script.value.Value; + +/** + * This class contains default Scarpet catchable exception's ids, as well as their inheritance and + * methods to check whether filters are compatible with those. + * + * Exceptions here cannot be thrown as an actual {@link Throwable}, they are just part of the metadata for + * {@link ThrowStatement} + */ +public class Throwables { + private static final Map byValue = new HashMap<>(); + public static final Exception EXCEPTION = register("exception", null); + public static final Exception VALUE_EXCEPTION = register("value_exception", EXCEPTION); + public static final Exception UNKNOWN_ITEM = register("unknown_item", VALUE_EXCEPTION); + public static final Exception UNKNOWN_BLOCK = register("unknown_block", VALUE_EXCEPTION); + public static final Exception UNKNOWN_BIOME = register("unknown_biome", VALUE_EXCEPTION); + public static final Exception UNKNOWN_SOUND = register("unknown_sound", VALUE_EXCEPTION); + public static final Exception UNKNOWN_PARTICLE = register("unknown_particle", VALUE_EXCEPTION); + public static final Exception UNKNOWN_POI_TYPE = register("unknown_poi_type", VALUE_EXCEPTION); + public static final Exception UNKNOWN_DIMENSION = register("unknown_dimension", VALUE_EXCEPTION); + public static final Exception UNKNOWN_STRUCTURE = register("unknown_structure", VALUE_EXCEPTION); + public static final Exception UNKNOWN_CRITERION = register("unknown_criterion", VALUE_EXCEPTION); + public static final Exception FILE_READ_EXCEPTION = register("file_read_exception", EXCEPTION); + public static final Exception NBT_READ = register("nbt_read_exception", FILE_READ_EXCEPTION); + public static final Exception JSON_READ = register("json_read_exception", FILE_READ_EXCEPTION); + public static final Exception USER_DEFINED = register("user_defined_exception", EXCEPTION); + protected static final Exception ERROR = register("error", null); + + private Throwables() {} + + /** + * Creates an exception and registers it to be used as parent for + * user defined exceptions in Scarpet's throw function. + *

Scarpet exceptions should, in general, have a top-level parent being {@link Throwables#EXCEPTION} + * @param name The name for the exception. Will be converted into a {@link StringValue} + * @param parent The parent of the exception being created, or null if top-level + * @return The created exception + */ + protected static Exception register(String value, Exception parent) + { + Exception exc = new Exception(value, parent); + byValue.put(exc.getValue(), exc); + return exc; + } + + /** + * The data of a {@link ThrowStatement} exception. Supports creating with inheritance and + * checking whether a filter is compatible with them. + */ + public static class Exception { + private final Value value; + private final Exception parent; + private final boolean isError; + + /** + * Creates a new exception, with an optional parent. + *

To be used in Scarpet's throw command + *

Parent will default to {@link Throwables#USER_DEFINED} if provided + * parentValue meets Value#isNull, else it will create a new {@link Exception}, + * with its parent being {@link Throwables#USER_DEFINED}. + * @param name The name/id of the exception + * @param parentValue An optional Value matching the name of a parent exception. + *
Accepts a {@link NullValue}, but not a null + */ + public Exception(Value value, Value parentValue) + { + if (byValue.containsKey(value)) + throw new InternalExpressionException("Exception id can't be the same as existing exception. Use it as parent instead"); + this.value = value; + if (!parentValue.isNull()) + { + Exception possibleParent = byValue.get(parentValue); + parent = possibleParent == null ? new Exception(parentValue, Value.NULL) : possibleParent; + } else + parent = USER_DEFINED; + isError = this.parent == ERROR; + } + + /** + * Creates a new exception. + *

Not suitable for creating exceptions that can't be caught. + * Use an {@link InternalExpressionException} for that + * @param name The exception's name/id + * @param parent The parent exception, or null if no parent is available + */ + protected Exception(String value, Exception parent) + { + this.value = StringValue.of(value); + this.parent = parent; + this.isError = false; + } + + /** + * Checks whether the given filter matches an instance of this exception, including checking equality + * with itself and possible parents. + * @param filter The value to check against + * @return Whether or not the given value matches this exception's hierarchy + */ + public boolean isInstance(Value filter) { + return getValue().equals(filter) || (parent != null && parent.isInstance(filter)); + } + + /** + * Returns the {@link Value} provided when creating this exception + * @return The {@link Value} of this exception + */ + public Value getValue() { + return value; + } + + /** + * Returns whether this exception has been defined as an error. + *

Error exceptions cannot be caught in Scarpet + * @return Whether this exception has been defined as an error + */ + public boolean isError() { + return isError; + } + } +} diff --git a/src/main/java/carpet/script/language/ControlFlow.java b/src/main/java/carpet/script/language/ControlFlow.java index 309f4f5b..076a29eb 100644 --- a/src/main/java/carpet/script/language/ControlFlow.java +++ b/src/main/java/carpet/script/language/ControlFlow.java @@ -49,13 +49,15 @@ public class ControlFlow { switch (lv.size()) { case 0: - throw new ThrowStatement("No further information", Value.NULL); + throw new ThrowStatement(new StringValue("No further information"), Value.NULL, Value.NULL); case 1: throw new ThrowStatement(lv.get(0).evalValue(c)); case 2: - throw new ThrowStatement(lv.get(1).evalValue(c).getString(), lv.get(0).evalValue(c)); + throw new ThrowStatement(lv.get(1).evalValue(c), lv.get(0).evalValue(c), Value.NULL); + case 3: + throw new ThrowStatement(lv.get(1).evalValue(c), lv.get(0).evalValue(c), lv.get(2).evalValue(c)); default: - throw new InternalExpressionException("throw() can't accept more than 2 parameters"); + throw new InternalExpressionException("throw() can't accept more than 3 parameters"); } }); @@ -70,17 +72,23 @@ public class ControlFlow { } catch (ProcessedThrowStatement ret) { + if (ret.exception.isError()) + throw ret; if (lv.size() == 1) return (c_, t_) -> Value.NULL; LazyValue __ = c.getVariable("_"); - c.setVariable("_", (__c, __t) -> ret.exceptionName.reboundedTo("_")); + c.setVariable("_", (__c, __t) -> ret.exception.getValue().reboundedTo("_")); LazyValue __msg = c.getVariable("_msg"); c.setVariable("_msg", (__c, __t) -> StringValue.of(ret.message).reboundedTo("_msg")); Value val; if (lv.size() == 3) { - if (!ret.exceptionName.equals(lv.get(1).evalValue(c))) + if (!ret.exception.isInstance(lv.get(1).evalValue(c))) + { + c.setVariable("_", __); + c.setVariable("_msg", __msg); throw ret; + } val = lv.get(2).evalValue(c, t); } else diff --git a/src/main/java/carpet/script/utils/ShapeDispatcher.java b/src/main/java/carpet/script/utils/ShapeDispatcher.java index ac24c46f..84aab23a 100644 --- a/src/main/java/carpet/script/utils/ShapeDispatcher.java +++ b/src/main/java/carpet/script/utils/ShapeDispatcher.java @@ -5,6 +5,7 @@ import carpet.network.ServerNetworkHandler; import carpet.script.CarpetContext; import carpet.script.exception.InternalExpressionException; import carpet.script.exception.ThrowStatement; +import carpet.script.exception.Throwables; import carpet.script.language.Sys; import carpet.script.value.BlockValue; import carpet.script.value.EntityValue; @@ -157,7 +158,7 @@ public class ShapeDispatcher } catch (CommandSyntaxException e) { - throw new ThrowStatement("No such particle: "+name, ThrowStatement.UNKNOWN_PARTICLE); + throw new ThrowStatement("No such particle: "+name, Throwables.UNKNOWN_PARTICLE); } particleCache.put(name, particle); return particle; diff --git a/src/main/java/carpet/script/value/BlockValue.java b/src/main/java/carpet/script/value/BlockValue.java index 56846d9b..fe26f57f 100644 --- a/src/main/java/carpet/script/value/BlockValue.java +++ b/src/main/java/carpet/script/value/BlockValue.java @@ -3,6 +3,7 @@ package carpet.script.value; import carpet.script.CarpetContext; import carpet.script.exception.InternalExpressionException; import carpet.script.exception.ThrowStatement; +import carpet.script.exception.Throwables; import com.mojang.brigadier.StringReader; import com.mojang.brigadier.exceptions.CommandSyntaxException; @@ -75,7 +76,7 @@ public class BlockValue extends Value catch (CommandSyntaxException ignored) { } - throw new ThrowStatement("Cannot parse block: "+str, ThrowStatement.UNKNOWN_BLOCK); + throw new ThrowStatement("Cannot parse block: "+str, Throwables.UNKNOWN_BLOCK); } public static BlockPos locateBlockPos(CarpetContext c, int xpos, int ypos, int zpos) diff --git a/src/main/java/carpet/script/value/NBTSerializableValue.java b/src/main/java/carpet/script/value/NBTSerializableValue.java index 1a790c2b..11595d06 100644 --- a/src/main/java/carpet/script/value/NBTSerializableValue.java +++ b/src/main/java/carpet/script/value/NBTSerializableValue.java @@ -5,6 +5,7 @@ import carpet.script.CarpetContext; import carpet.script.LazyValue; import carpet.script.exception.InternalExpressionException; import carpet.script.exception.ThrowStatement; +import carpet.script.exception.Throwables; import carpet.script.utils.EquipmentInventory; import com.mojang.brigadier.StringReader; import com.mojang.brigadier.exceptions.CommandSyntaxException; @@ -298,7 +299,7 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa } catch (CommandSyntaxException e) { - throw new ThrowStatement("Incorrect item: "+itemString, ThrowStatement.UNKNOWN_ITEM); + throw new ThrowStatement("Incorrect item: "+itemString, Throwables.UNKNOWN_ITEM); } } diff --git a/src/main/java/carpet/script/value/ValueConversions.java b/src/main/java/carpet/script/value/ValueConversions.java index 9fc4e62f..320916ae 100644 --- a/src/main/java/carpet/script/value/ValueConversions.java +++ b/src/main/java/carpet/script/value/ValueConversions.java @@ -3,6 +3,7 @@ package carpet.script.value; import carpet.fakes.BlockPredicateInterface; import carpet.script.exception.InternalExpressionException; import carpet.script.exception.ThrowStatement; +import carpet.script.exception.Throwables; import carpet.utils.BlockInfo; import net.minecraft.block.BlockState; import net.minecraft.block.MaterialColor; @@ -159,7 +160,7 @@ public class ValueConversions } } if (dim == null) - throw new ThrowStatement("Incorrect dimension string: "+dimString, ThrowStatement.UNKNOWN_DIMENSION); + throw new ThrowStatement("Incorrect dimension string: "+dimString, Throwables.UNKNOWN_DIMENSION); return server.getWorld(dim); } }