MAXScript provides simple exception-handling with the try
expression, a simplified form of the C++ exception-handling scheme.
The try
expression lets you bracket a piece of code and catch any runtime errors.
This allows you to respond appropriately or take corrective action, rather than let MAXScript halt the execution of your script and print an error message.
The syntax for the try
expression is:
try <protected_expr> catch <on_err_expr>
The <protected_expr>
is executed and any errors that occur are trapped and the <on_err_expr>
is executed.
If the <protected_expr>
is a block-expression, the block-expression stops executing at the point of the error.
If there are no errors in the protected expression, the <on_err_expr>
is not executed.
This is a very simple error-trapping scheme, but limited heavily by the fact that you only get limited error codes or information about the error that occurred. See getCurrentException() below.
EXAMPLE:
f = openFile "foo.dat" try while not eof f do read_some_data f catch ( messageBox "bad data in foo.dat" results = undefined ) close f
In this example, any errors in reading or processing the data in the read_some_data()
function are trapped, then a Message box is displayed and some clean-up is done.
This is a good example of a use for the simple error-trapping.
There is also an associated function, throw()
, which can be used to generate your own runtime error and pass on an error you caught when doing some interim clean-up, or do a non-local jump.
It has the form:
throw <error_message_string> [ <value> ] [ debugBreak:<boolean> ]
throw()
If you have no intervening catches in your script, calling throw()
with error message arguments will cause a runtime error to be signaled and MAXScript will report the error message using its standard error reporting.
The optional <value>
argument can be any value you want printed with the error message, perhaps the object involved in the error. This argument can not be specified if the throw
is in the body of a catch()
and will generate a compile error if present.
The optional debugBreak:<boolean>
argument specifies whether to break and display the MAXScript Debugger window. The default setting for this argument is set by the MAXScript Debugger configuration setting "Default Throw debugBreak:on", which you can query with the MXSDebugger.defaultBreakOnThrow property. Note that even if specified as true, if the "Allow Break On Throw" option is disabled for the debugger, the debugger will not display. You can query this setting with the MXSDebugger.allowBreakOnThrow property.
If the try
/ catch
is within another try
expression, calling throw()
will cause the catch
expression associated with the outer try
expression to be executed.
If you have no intervening catches in your script, calling throw()
will cause MAXScript to continue running the script from just after the top-most set of parenthesis surrounding the try
/ catch
, or will stop the currently running script if there are no parenthesis surrounding the try
/ catch
.
If you want to catch an error, perhaps to do some clean-up processing, and then pass the error on to outer handlers or MAXScript for error reporting, you can call throw()
with no arguments.
This throws the current error again and must only be done inside a catch
expression.
EXAMPLE:
try ( i=10 try ( i.x=1 ) -- will generate a run-time error catch ( print "Bad Error" -- error message printed try (i.pos=[0,0,0]) -- will also generate a run-time error catch (throw()) -- throw() will cause outer catch -- to execute ) ) catch (print "Really Bad Error Occurred") -- error message printed
getCurrentException()
This method returns the text of the current exception.
It is only useful inside a catch statement - if used outside a catch, it will return 'undefined'.
EXAMPLE:
try ( throw "AAAAA" ) catch ( format "*** % ***\n" (getCurrentException()) )
RESULT:
*** -- Runtime error: AAAAA ***
hasCurrentExceptionStackTrace()
Available since 3ds Max 2017: Returns true if a MAXScript stack trace is available. It is only useful inside a catch statement - if used outside a catch, it will return false. It should always return true within a catch.
hasCurrentExceptionCallStack()
Available since 3ds Max 2017: Returns true if a C++ stack trace is available. It is only useful inside a catch statement - if used outside a catch, it will return false. Within a catch, it will be true only if the exception that was caught was a system exception, such as an access violation or an integer divide by 0.
getCurrentExceptionStackTrace()
Available since 3ds Max 2017: Returns the MAXScript stack trace as a string. It is only useful inside a catch statement - if used outside a catch, it will return false. It should always return true within a catch.
getCurrentExceptionCallStack()
Available since 3ds Max 2017: Returns the C++ stack trace captured at the time an exception was thrown, as a string. It is only useful inside a catch statement - if used outside a catch, it will return 'undefined'. Within a catch, if the C++ stack trace was not captured, an empty string is returned.
CaptureCallStack [skipFirstNStackLevels:<int>]
Available since 3ds Max 2017: Captures the MAXScript call stack. The skipFirstNStackLevels
parameter defaults to 3 if not specified.
<string> getErrorSourceFileName()
Available since 3ds Max 2018: Returns the name of the source file causing the error, when called inside a catch statement. This can be useful if running code from multiple scripts, for example by using fileIn()
.
undefined
.<integer> getErrorSourceFileLine()
Available since 3ds Max 2018: Returns the line number where the error occurred, when called inside a catch statement..
undefined
.<integer> getErrorSourceFileOffset()
Available since 3ds Max 2018: Returns offset where the error occurred, when called inside a catch statement. This is the end of the expression being evaluated, including any comments.
undefined
.