20: Exceptions - royal-lang/rl GitHub Wiki
Royal has support for exceptions but exceptions can only be used in throwing functions. That's because the nature of exceptions should be exceptional and avoided as much as possible.
This means by default all functions will be checked if they can possibly throw an exception and if that's the case they will yield a compiler error unless marked throwing.
Exceptions shouldn't be used unless absolutely necessary. The goal is to have code that generally doesn't have errors, of course that isn't always the case and thus exceptions are supported.
An exception thrown must be a ref struct that has inherited the Exception ref struct.
Only a throwing function can call another throwing function unless they call the throwing function within a try/catch statement.
ref struct MyException : Exception
{
this(string msg)
{
super(msg);
}
}
throw MyException("An error happened ...");
Example:
throwing:
fn throwError()
{
throw Exception("Error ...");
}
throwing:
fn callThrowError()
{
throwError();
}
throwing:
fn main()
{
callThrowError();
}
Exception Stack Trace:
throwError();
callThrowError();
main();
By default the stack trace is kept for throwing functions but you can set the nostracktrace attribute of the first throwing function to disable the stack trace which will keep the stack trace to the function that threw only.
This can help improve performance around stacktrace creation etc.
Example:
throwing:
fn throwError()
{
throw Exception("Error ...");
}
throwing:
nostacktrace:
fn callThrowError()
{
throwError();
}
throwing:
fn main()
{
callThrowError();
}
Exception Stack Trace:
throwError();
To call a throwing function from within a non-throwing function you must use a try/catch statement.
Empty catch statements are prohibited in Royal.
You can also declare a finally scope which will be run when the try/catch scope has been executed. This is run regardless of whether an exception happened or not.
try
{
}
catch (EXCEPTION)
{
}
finally
{
}
try
{
}
catch (EXCEPTION1)
{
}
catch (EXCEPTION2)
{
}
try
{
}
catch (EXCEPTION1,EXCEPTION2)
{
}
Example:
try
{
throwError();
}
catch (Exception e)
{
writeln(e);
}