Exceptions are thrown by functions at runtime. Since MScript is not strongly typed, it is not possible to catch all errors at compile time. Due to this, it is useful to be able to programmatically determine if a function failed. To this end, since version 3.1.2, MScript has the
try() function. This function takes 3 or 4 arguments:
try(try_code, ivar, catch_code, [interested_types])
If you are familiar with other programming languages' try-catch mechanisms, then this construct will be familiar. The code at
try_code is run normally. If any function in the code causes an exception to be thrown, execution will halt, and program flow will start at
catch_code. The exception thrown will be stored in
ivar, so that you can programmatically examine the cause of the exception. Many times, you are only interested in a certain type of exception. This is where the optional
interested_types variable comes in. If omitted, all exceptions are caught. If provided, it may be a single string, or an array of strings, where the provided values are one or more of the exception types listed below. There are a select few errors that can be caused by runtime issues which cannot be caught, but by far, most runtime issues can be caught in a try function. In addition, you can trigger an exception being thrown with the
throw accepts any valid exception type listed below, as well as a message. The line number will automatically be added. This exception is then passed up the chain, just as if any other function had thrown the exception. If the exception type is null, this exception is uncatchable, however, it is best practice to use the
die() function if you intend on killing a script.
If an exception is passed all the way to the root of the script, and the interpreter has to catch the exception, the script will terminate, and the default message will be logged to console, and displayed to the user. In most cases, this may be enough. Also, in general, exceptions have been massively improved, all exceptions give a much more detailed error message, and also provide a line number to assist in debugging your scripts. Also note that if debug-mode is on, ALL exceptions that are thrown will log to the console, even if they are caught. This can help debug a potential problem with your script. The API has been updated to include a list of possible exceptions that can be thrown by a function, and a list of what the exception types are, and what might cause them to be thrown are listed below. Please note that it is entirely possible that an exception being thrown was not noted in the API -- this is a bug in the documentation. Please report it so that it can be corrected. Also note that it is possible for the try function itself to throw an exception, if the arguments are not of the proper type. Though it is possible to further catch those exceptions, it probably means that your code is poorly designed.
When accepting user input, it is important to verify that their input is valid. Using exceptions allows you to easily catch errors in their input.
/test $index= >>> # Assign an array to the variable @a assign(@a, array('0', '1', '2')) # array_get can possibly throw an IndexOverflowException, or a CastException try( msg(array_get(@a, $index)) , @ex, # The zeroth element in the exception tells us the exception type. # That is important to get here, so we display proper error messages if(equals(array_get(@ex, 0), IndexOverflowException) , die('That index is not valid') , die('Please enter an actual number') ) # We could have left this blank, but this allows us to more precisely filter our exceptions , array(IndexOverflowException, CastException)) <<<
Non-Exception data validation
In addition to exception handling in 3.1.2, several functions have been added that allow you to validate data without using the try-catch framework. Make note of the existence of the following functions:
These functions will allow you to validate that the data entered is in fact of the specified type, or can be cast to the specified type.
Both the spelling and capitalization are important when using the name of an exception. The proper format is displayed in the header of each section.
This exception is thrown if a value cannot be cast into an appropriate type. Functions that require a numeric value, for instance, would throw this if the string "hi" were passed in.
This exception is thrown if a value is requested from an array that is above the highest index of the array, or a negative number.
This exception is thrown if a function expected a numeric value to be in a particular range, and it wasn't. Generally, this will be obvious as to what the function expects.
This exception is thrown if a function expected the length of something to be a particular value, but it was not.
This exception is thrown if the user running the command does not have permission to run the function
This exception is thrown if a function expected an online player, but that player was offline, or otherwise doesn't exist
Some var arg functions may require at least a certain number of arguments to be passed to the function
This exception is thrown if a function expected a string to be formatted in a particular way, but it could not interpret the given value.
This exception is thrown if a procedure is used without being defined, or if a procedure name does not follow proper naming conventions.
This exception is thrown if there is a problem with an include. This is thrown if there is a compile error in the included script.
This exception is thrown if a script tries to read or write to a location of the filesystem that is not allowed.
This exception is thrown if a file cannot be read or written to.
This exception is thrown if a function uses an external plugin, and that plugin is not loaded, or otherwise unusable.
This exception is thrown when a plugin is loaded, but a call to the plugin failed, usually for some reason specific to the plugin. Check the error message for more details about this error.
If a function requests a world, and the world given doesn't exist, this is thrown