Errors
SandScript uses throw signals for all exceptional conditions.
Error values are values. A program can throw a string, an object,
or an instance of a built-in error family such as
Error or TypeError.
// Throwing
throw "Simple error message";
throw { type: "ValidationError", message: "Invalid input" };
// Catching
try {
riskyOperation();
} catch (e) {
Console.log(e.message);
}
Rich error context
Interpreter-generated errors carry structured context as extra properties on the error object:
try {
let dv = new DataView(new ArrayBuffer(4))
dv.getInt16(5)
} catch (e) {
e.message // "Offset is outside the bounds of the DataView"
e.offset // 5
e.bufferLength // 4
e.elementSize // 2
}
try {
let x = null
x.foo
} catch (e) {
e.message // "Cannot read property of null"
e.type // 1 (type tag for null)
}
try {
undeclaredVar
} catch (e) {
e.message // "Not defined"
e.identifier // "undeclaredVar"
}
When an error goes uncaught, the runtime builds a detailed diagnostic message from these properties:
RangeError: Offset 5 is outside the bounds of the DataView (2-byte access, buffer length 4)
TypeError: Not a function (received number)
ReferenceError: undeclaredVar is not defined
Why no stack traces
SandScript does not provide stack traces inside the language, for two reasons:
- Mutability. Code lives in linear memory, and the host can mutate it during execution. A stack trace captured at throw time could contain stale references.
- Synthetic code. Code that causes an error does not have to come from parsed text. Line numbers mean nothing for dynamically constructed code.
Stack traces are a host and debugger concern, not a language feature.