You are viewing an older version of the site. Click here to view
the latest version of this page. (This may be a dead link, if so, try the root page of the docs
here.)
Exceptions can be thrown by various functions at runtime. This indicates that there was some issue with the
input data. There is a straightforward way to deal with these errors however, using a try/catch block.
== Example ==
A good example is code that takes a user input. Assume that we want to validate that the user has provided us
with an integer like string. We might write the following:
Copy Code
In this case, if the user input procedure returns
Copy Code
This will message the user if the value is not correct, using a custom error message.
== Multicatch ==
Sometimes, a block of code might throw multiple types of exceptions, and we want to handle each type differently.
Perhaps our
Copy Code
Each catch block will only run if the exception thrown matches the type. If an exception is thrown that doesn't
match any of the types, it will continue up the stack as if there were no try/catch in place at that point.
=== Catch clause specificity ===
When an exception is thrown, the catch clauses are checked one by one, in declaration order, for exception matches.
This means that you should order your catch clauses from most specific to least specific. Consider the following code:
Copy Code
Be sure to always order your catch clauses appropriately.
== The exception object ==
The exception that is thrown is an associative array that has some perhaps useful information in it, such as the exception
message, line number, and things like that. Here is an implementation of the default handling, except it is being handled
from within the script.
Copy Code
The above example demonstrates the complex usage of the exception object. In addition, it's worth noting that if you are
having trouble with code, you could get a stacktrace by throwing and catching a custom exception, however, it's more
straightforward to use {{function|get_stack_trace}}
== The Throwable type ==
All exceptions extend the Exception type, which further extends the Throwable type. Another type of Throwable is
a the Error type (and subclasses). If you specifically catch Errors, they can be caught, but this is not recommended,
as it usually indicates a very severe error. While it is possible to directly catch a Throwable of any type, you should
generally not catch that, and instead catch specific types that you are interested in, or Exception, if need be.
== Throwing your own exceptions ==
You may also throw your own exceptions. See the documentation for {{functions|throw}} for more information.
== finally clause ==
Sometimes you may want to run code after the try block, regardless of what happens in the try block, including successful
invocation of the code, an exception being thrown and further exceptions being thrown from the catch block,
or simply return()ing in the try block. The finally clause
can be used to accomplish this. The finally clause must come after all catch clauses, but may be used even if no
catch clauses are defined (this is called a try/finally block). This is most useful for cleanup that needs to happen
regardless of how the code exited.
There are three specific examples that this might be useful for:
# If code within the `try` block exits via `return`
# If code within a catch block either rethrows the caught exception, or--accidentally or intentionally--ends up throwing a new one.
# If the code within the `try` block encounters an exception for which there is no catch.
Take the following examples:
Copy Code
Copy Code
Copy Code
== Caused By, and rethrowing ==
Exceptions might need to be rethrown. This is supported by {{function|throw}}. For instance:
Copy Code
This can be used if you want to conditionally handle the exception, but continue to throw the exception up the
chain in other cases.
You may find that you have to throw an exception due to another exception. To do this, you may also used the Caused By mechanism. This will
cause the exception to chain. This is also supported with {{function|throw}}.
Copy Code
This can be useful for times that you need to throw another exception from within the catch block, but don't want to hide
the original exception, or when you need to otherwise wrap the original exception. It is quite useful to know what exception
originally caused this chain. This can be accessed from the , the class would need to be both a superclass of mixed and a subclass of number, a state which is impossible to be in.
Since: 3.3.5
===ms.lang.IOException===
This exception is thrown if a file cannot be read or written to.
Since: 3.3.1
===ms.lang.IllegalArgumentException===
Thrown if an argument was illegal in the given context.
Since: 3.3.1
===ms.lang.IncludeException===
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.
Since: 3.3.1
===ms.lang.IndexOverflowException===
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.
Since: 3.3.1
===ms.lang.InsufficientArgumentsException===
Some var arg functions may require at least a certain number of arguments to be passed to the function
Since: 3.3.1
===ms.lang.InsufficientPermissionException===
This exception is thrown if the user running the command does not have permission to run the function
Since: 3.3.1
===ms.lang.InterruptedException===
This exception is thrown if the given operation is interrupted.
Since: 3.3.4
===com.commandhelper.InvalidPluginException===
This exception is thrown if a function uses an external plugin, and that plugin is not loaded, or otherwise unusable.
Since: 3.3.1
===ms.lang.InvalidProcedureException===
This exception is thrown if a procedure is used without being defined, or if a procedure name does not follow proper naming conventions.
Since: 3.3.1
===com.commandhelper.InvalidWorldException===
If a function requests a world, and the world given doesn't exist, this is thrown
Since: 3.3.1
===ms.lang.LengthException===
This exception is thrown if a function expected the length of something to be a particular value, but it was not.
Since: 3.3.1
===ms.lang.NotFoundException===
Thrown if data was not found, but expected.
Since: 3.3.1
===ms.lang.NullPointerException===
If a null is sent, but not expected, this exception is thrown. Additionally, this is thrown if null is dereferenced.
Since: 3.3.1
===ms.lang.auth.OAuthException===
This exception is thrown in cases where the OAuth system failed.
Since: 3.3.2
===com.commandhelper.PlayerOfflineException===
This exception is thrown if a function expected an online player, but that player was offline, or the command is being run from somewhere not in game, and the function was trying to use the current player.
Since: 3.3.1
===com.commandhelper.PluginChannelException===
Thrown if trying to register a plugin channel that is already registered, or unregister one that isn't registered.
Since: 3.3.1
===ms.lang.PluginInternalException===
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.
Since: 3.3.1
===ms.lang.RangeException===
This exception is thrown if a function expected a numeric value to be in a particular range, and it wasn't
Since: 3.3.1
===ms.lang.ReadOnlyException===
Thrown if a field was read only, but a write operation was attempted.
Since: 3.3.1
===ms.lang.SQLException===
Thrown if an SQL related exception occurs.
Since: 3.3.1
===com.commandhelper.ScoreboardException===
Thrown if a scoreboard error occurs, such as attempting to create a team or objective with a name that is already in use, or trying to access one that doesn't exist.
Since: 3.3.1
===ms.lang.SecurityException===
This exception is thrown if a script tries to read or write to a location of the filesystem that is not allowed.
Since: 3.3.1
===ms.lang.ShellException===
Thrown if a shell exception occurs.
Since: 3.3.1
===ms.lang.StackOverflowError===
Thrown if a stack overflow error happens. This can occur if a function recurses too deeply.
Since: 3.3.1
===ms.lang.Throwable===
All throwable types must extend this class. Otherwise, they will not be allowed to be thrown by the in script system.
Since: 3.3.1
===com.commandhelper.UnageableMobException===
If an age function is called on an unageable mob, this exception is thrown.
Since: 3.3.1
===ms.lang.UnsupportedOperationException===
If an operation is not supported, this exception can be thrown.
Since: 3.3.4
===com.commandhelper.UntameableMobException===
If an untameable mob is attempted to be tamed, this exception is thrown
Since: 3.3.1
{{LearningTrail}}
@userInput = _getUserInput();
@value = integer(@userInput);
_doSomethingWithTheValue(@value);
Copy Code1 @userInput = {{function|_getUserInput}}();
2 @value = {{function|integer}}(@userInput);
3 {{function|_doSomethingWithTheValue}}(@value);
'2', then the code will work as intended. If it
returns 'string' however, it will throw an exception. As it stands, with no exception handling in
place, you would see a similar error to this:
CastException: Expecting a double, but received string instead
at proc _throw:/home/user/include2.ms:13.3
at <<include include2.ms>>:/home/user/include2.ms:16.2
at <<include include1.ms>>:/home/user/include1.ms:10.2
at <<closure>>:/home/user/test.ms:12.3
The stack trace can help you trace back the actual error, as the error itself is not necessarily with the top
line in the stacktrace, which is where the actual exception was thrown. Instead, it might be because you're
passing in an invalid parameter to a proc, so it may be useful to step back a few items in the stack trace to
see what's calling what. Several things are added to the stack trace, particularly procedure stack, but also
closures and includes.
This is the default exception handling mechanism. It prints out the exception type, exception message, and a
stacktrace. But perhaps we want to print a custom message to the user. In this case, we can trap the exception
using a try/catch block, and handle it in a custom way. In this case, we want to "catch" the CastException that
is "thrown".
try {
@userInput = _getUserInput();
@value = integer(@userInput); // Can throw CastException
_doSomethingWithTheValue(@value);
} catch(CastException @e){
// This will run if integer(@userInput) throws a CastException
msg("The value must be an integer");
}
Copy Code1 {{keyword|try}} {
2 @userInput = {{function|_getUserInput}}();
3 @value = {{function|integer}}(@userInput); // Can throw CastException
4
5 {{function|_doSomethingWithTheValue}}(@value);
6 } {{keyword|catch}}({{object|CastException}} @e){
7 // This will run if integer(@userInput) throws a CastException
8
9 {{function|msg}}("The value must be an integer");
10 }
_doSomethingWithTheValue procedure was capable of throwing an IOException. We ''could'' wrap
the entire block in a second try catch block, but there's an easier way, using multicatch.
try {
@userInput = _getUserInput();
@value = integer(@userInput); // Can throw CastException
_doSomethingWithTheValue(@value); // Can throw IOException
} catch(CastException @e) {
msg("The value must be an integer");
} catch(IOException @e) {
msg("There was an error with the disk, and your request could not be completed.");
}
Copy Code1 {{keyword|try}} {
2 @userInput = {{function|_getUserInput}}();
3 @value = {{function|integer}}(@userInput); // Can throw CastException
4
5 {{function|_doSomethingWithTheValue}}(@value); // Can throw IOException
6
7 } {{keyword|catch}}({{object|CastException}} @e) {
8 {{function|msg}}("The value must be an integer");
9 } {{keyword|catch}}({{object|IOException}} @e) {
10 {{function|msg}}("There was an error with the disk, and your request could not be completed.");
11 }
try {
code();
} catch(Exception @e){
msg("Will catch the exception");
} catch(IOException @e){
msg("Will never run, because the catch-Exception clause will always catch the exception first, because"
. " IOException extends Exception");
}
Copy Code1 {{keyword|try}} {
2 {{function|code}}();
3 } {{keyword|catch}}({{object|Exception}} @e){
4 {{function|msg}}("Will catch the exception");
5 } {{keyword|catch}}({{object|IOException}} @e){
6 {{function|msg}}("Will never run, because the catch-Exception clause will always catch the exception first, because"
7 . " IOException extends Exception");
8 }
try {
code();
} catch(CastException @e) {
@classType = @e['classType'];
@message = @e['message'];
@stackTrace = @e['stackTrace'];
msg(colorize("&c@classType&f: @message"));
foreach(@element in @stackTrace){
@procedureName = @element['id']; // This could be a procedure or a closure, or a few other things
@file = @element['file'];
@line = @element['line'];
msg(colorize("\t&a@procedureName&f:&6@file&f:&b@line"));
}
}
Copy Code01 {{keyword|try}} {
02 {{function|code}}();
03 } {{keyword|catch}}({{object|CastException}} @e) {
04 @classType = @e['classType'];
05 @message = @e['message'];
06 @stackTrace = @e['stackTrace'];
07 {{function|msg}}({{function|colorize}}("&c@classType&f: @message"));
08 {{keyword|foreach}}(@element {{keyword|in}} @stackTrace){
09 @procedureName = @element['id']; // This could be a procedure or a closure, or a few other things
10
11 @file = @element['file'];
12 @line = @element['line'];
13 {{function|msg}}({{function|colorize}}(" &a@procedureName&f:&6@file&f:&b@line"));
14 }
15 }
try {
@value = codeThatOpensAResource();
return(@value);
} finally {
cleanUpResource();
}
Copy Code1 {{keyword|try}} {
2 @value = {{function|codeThatOpensAResource}}();
3 {{function|return}}(@value);
4 } {{keyword|finally}} {
5 {{function|cleanUpResource}}();
6 }
try {
code();
} catch(Exception @e) {
throw(IOException, "Another exception");
} finally {
// This section still runs
}
Copy Code1 {{keyword|try}} {
2 {{function|code}}();
3 } {{keyword|catch}}({{object|Exception}} @e) {
4 {{function|throw}}({{object|IOException}}, "Another exception");
5 } {{keyword|finally}} {
6 // This section still runs
7
8 }
try {
codeThatThrowsANullPointerException();
} catch(IOException @e) {
// This block won't be run in this case
} finally {
// This code runs anyways, though the NPE will be thrown further up
}
Copy Code1 {{keyword|try}} {
2 {{function|codeThatThrowsANullPointerException}}();
3 } {{keyword|catch}}({{object|IOException}} @e) {
4 // This block won't be run in this case
5
6 } {{keyword|finally}} {
7 // This code runs anyways, though the NPE will be thrown further up
8
9 }
try {
throw(IOException, 'message');
} catch(IOException @e){
if(/* some condition is true */){
// We don't care about this exception
} else {
throw(@e);
}
}
Copy Code1 {{keyword|try}} {
2 {{function|throw}}({{object|IOException}}, 'message');
3 } {{keyword|catch}}({{object|IOException}} @e){
4 {{keyword|if}}(/* some condition is true */
5 ){
6 // We don't care about this exception
7
8 } {{keyword|else}} {
9 {{function|throw}}(@e);
10 }
11 }
try {
try {
throw(IOException, 'ioexception');
} catch(IOException @e){
throw(CastException, 'castexception', @e);
}
} catch(CastException @e){
msg(@e['causedBy']); // This will be the IOException
}
Copy Code1 {{keyword|try}} {
2 {{keyword|try}} {
3 {{function|throw}}({{object|IOException}}, 'ioexception');
4 } {{keyword|catch}}({{object|IOException}} @e){
5 {{function|throw}}({{object|CastException}}, 'castexception', @e);
6 }
7 } {{keyword|catch}}({{object|CastException}} @e){
8 {{function|msg}}(@e['causedBy']); // This will be the IOException
9
10 }
causedBy index in the exception object.
== Old usage ==
There is an old, now deprecated usage as well, see the article [[OldExceptions|here]]
for information on how to use it. For new code, however, the new format should always be used.
== Known Exception Types ==
Exception types can be added by extension authors, but here is a list (and documentation) for all known exceptions.
===ms.lang.ByteArrayReadOnlyException===
An exception which is thrown if the array copied from a byte array is attempted to be written to.
Since: 3.3.1
===com.commandhelper.BadEntityException===
Thrown if an entity is looked up by id, but doesn't exist.
Since: 3.3.1
===com.commandhelper.BadEntityTypeException===
Thrown if an entity has the wrong type.
Since: 3.3.1
===ms.lang.BindException===
This exception is thrown if an error occurs when trying to bind() an event, or if a event framework related error occurs.
Since: 3.3.1
===ms.lang.CastException===
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.
Since: 3.3.1
===ms.lang.ClassDefinitionError===
This is thrown if a class definition is incorrect. Normally this should be a compiler error, but in dynamic code cases, it may be a runtime error.
Since: 3.3.4
===com.commandhelper.EnchantmentException===
If an enchantment is added to an item that isn't supported, this is thrown.
Since: 3.3.1
===ms.lang.Error===
Indicates a serious error occurred. It is not recommended to catch Error directly, but instead catch a specific subtype.
Since: 3.3.1
===ms.lang.EventException===
Thrown if something is wrong with the event object. Usually this indicates a bigger problem with the server configuration or plugin issue, rather than an error in the script.
Since: 3.3.2
===ms.lang.Exception===
A generic exception. All normal exceptions extend this type.
Since: 3.3.1
===ms.lang.FormatException===
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.
Since: 3.3.1
===ms.lang.CastException===
This exception is thrown if a generic definition has an invalid constraint combination. For instance, in the generic definition Find a bug in this page? Edit this page yourself, then submit a pull request.