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:

%%CODE|
@userInput = _getUserInput();
@value = integer(@userInput);
_doSomethingWithTheValue(@value);
%%

In this case, if the user input procedure returns <code>'2'</code>, then the code will work as intended. If it
returns <code>'string'</code> however, it will throw an exception. As it stands, with no exception handling in
place, you would see a similar error to this:

%%PRE|
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".

%%CODE|
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");
}
%%

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 <code>_doSomethingWithTheValue</code> 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.

%%CODE|
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.");
}
%%

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:

%%CODE|
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");
}
%%

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.

%%CODE|
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"));
	}
}
%%

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:

%%CODE|
try {
	@value = codeThatOpensAResource();
	return(@value);
} finally {
	cleanUpResource();
}
%%

%%CODE|
try {
	code();
} catch(Exception @e) {
	throw(IOException, "Another exception");
} finally {
	// This section still runs
}
%%

%%CODE|
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
}
%%

== Caused By, and rethrowing ==
Exceptions might need to be rethrown. This is supported by {{function|throw}}. For instance:

%%CODE|
try {
	throw(IOException, 'message');
} catch(IOException @e){
	if(/* some condition is true */){
		// We don't care about this exception
	} else {
		throw(@e);
	}
}
%%

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}}.

%%CODE|
try {
	try {
		throw(IOException, 'ioexception');
	} catch(IOException @e){
		throw(CastException, 'castexception', @e);
	}
} catch(CastException @e){
	msg(@e['causedBy']); // This will be the IOException
}
%%

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 <code>causedBy</code> 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.

%%EXCEPTION_TYPES%%

{{LearningTrail}}
