try {
throw "something went wrong";
} catch (String e) {
Konsol:Print("Caught: " + e);
} finally {
Konsol:Print("always runs");
}
throw accepts any expression; the string value becomes the exception message.(String e) is optional — bare catch { } works too.finally is optional.Use throw to raise an exception from your own code:
function validateAge(Number age) {
if (age < 0) { throw "age cannot be negative"; }
if (age > 150) { throw "age out of realistic range"; }
}
try {
validateAge(-5);
} catch (String e) {
Konsol:Print("Validation failed: " + e);
}
The engine raises typed exceptions for certain runtime errors:
MathException — division by zero; catch with catch (MathException e)ArrayException — out-of-bounds access; catch with catch (ArrayException e), e.code holds the attempted indexKonsolScript Error (line 5): undefined variable 'total'
5 | Konsol:Print(total);
| ^^^^^
Uncaught throw exceptions show the same context plus a full stack trace:
Uncaught exception (line 12): something went wrong
12 | throw "something went wrong";
Stack trace:
at inner (called from line 8)
at outer (called from line 3)
at main
Calling a method on a class that was never registered raises a clear error:
Runtime error at line 3: unknown class 'Sample' — missing #include?
// 08_errors.ks — try / catch / finally / throw
Konsol:Print("=== Error Handling ===");
// Basic try/catch
Konsol:Print("--- basic catch ---");
try {
Konsol:Print("before throw");
throw "something went wrong";
Konsol:Print("this should not print");
} catch (Exception e) {
Konsol:Print("caught: ${e.code}");
}
Konsol:Print("execution continues");
// finally always runs
Konsol:Print("--- finally ---");
try {
Konsol:Print("try block");
throw "oops";
} catch (String err) {
Konsol:Print("catch: ${err}");
} finally {
Konsol:Print("finally: always runs");
}
// finally without exception
Konsol:Print("--- finally (no exception) ---");
try {
Konsol:Print("no throw here");
} catch (String e) {
Konsol:Print("never reached");
} finally {
Konsol:Print("finally still runs");
}
// Catch without parameter
Konsol:Print("--- bare catch ---");
try {
throw "ignored message";
} catch {
Konsol:Print("caught without binding");
}
// Nested try/catch
Konsol:Print("--- nested ---");
try {
Konsol:Print("outer try");
try {
Konsol:Print("inner try");
throw "inner error";
} catch (String inner) {
Konsol:Print("inner catch: ${inner}");
throw "re-thrown from inner";
}
} catch (String outer) {
Konsol:Print("outer catch: ${outer}");
}
// Throw a number (converted to string)
Konsol:Print("--- throw number ---");
try {
throw 404;
} catch (String code) {
Konsol:Print("error code: ${code}");
}
// Conditional throw
Konsol:Print("--- conditional throw ---");
function divide(Number a, Number b) : Number {
if (b == 0) {
throw "division by zero";
}
return a / b;
}
try {
Var:Number r = divide(10, 2);
Konsol:Print("10 / 2 = ${r}");
Var:Number bad = divide(5, 0);
} catch (String e) {
Konsol:Print("caught from function: ${e}");
}
// 19_exception.ks — Exception class: structured errors, subclassing
Konsol:Print("=== Exception Class ===");
// Exception is a built-in class (extends Object):
// Fields: message (String), type (String), code (Number)
// Methods: init(String type, String message)
// toString() → "[type] message"
// getType() → "Exception" (inherited from Object)
// isInstanceOf(String t) → bool
// ── Basic Exception usage ─────────────────────────────────────────────────────
Konsol:Print("--- basic ---");
Class:Exception ex;
ex.init("RuntimeError", "something went wrong");
Var:String exStr;
exStr = ex.toString();
Konsol:Print("toString = ${exStr}");
Var:String exType;
exType = ex.getType();
Konsol:Print("getType = ${exType}");
Var:Boolean isExc;
isExc = ex.isInstanceOf("Exception");
Konsol:Print("isInstanceOf Exception = ${isExc}");
Var:Boolean isObj;
isObj = ex.isInstanceOf("Object");
Konsol:Print("isInstanceOf Object = ${isObj}");
// ── Throw and catch using Exception.message ───────────────────────────────────
Konsol:Print("--- throw + catch ---");
try {
Class:Exception e;
e.init("ValueError", "expected a positive number");
throw e.message;
} catch (String msg) {
Konsol:Print("caught: ${msg}");
}
// ── Using Exception in a guard function ───────────────────────────────────────
Konsol:Print("--- guard function ---");
function safeDivide(Number a, Number b) : Number {
if (b == 0) {
Class:Exception ex;
ex.type = "MathError";
ex.message = "division by zero";
ex.code = 100;
throw ex.message;
}
return a / b;
}
try {
Var:Number r = safeDivide(10, 2);
Konsol:Print("10 / 2 = ${r}");
Var:Number bad = safeDivide(5, 0);
} catch (String err) {
Konsol:Print("error: ${err}");
}
// ── Custom Exception subclass ─────────────────────────────────────────────────
Konsol:Print("--- subclassing Exception ---");
Class:Create(FileException extends Exception) {
Var:String filename;
function initFile(String fname, String msg) {
filename = fname;
type = "FileException";
message = msg;
}
function toString() : String {
return "[" + type + "] " + filename + ": " + message;
}
}
Class:FileException fe;
fe.initFile("data.txt", "file not found");
Var:String feStr;
feStr = fe.toString();
Konsol:Print("FileException toString = ${feStr}");
Var:String feType;
feType = fe.getType();
Konsol:Print("FileException getType = ${feType}");
Var:Boolean feIsFile;
feIsFile = fe.isInstanceOf("FileException");
Konsol:Print("isInstanceOf FileException = ${feIsFile}");
Var:Boolean feIsExc;
feIsExc = fe.isInstanceOf("Exception");
Konsol:Print("isInstanceOf Exception = ${feIsExc}");
Var:Boolean feIsObj;
feIsObj = fe.isInstanceOf("Object");
Konsol:Print("isInstanceOf Object = ${feIsObj}");
// Throw and catch a FileException
try {
Class:FileException e;
e.initFile("config.json", "permission denied");
throw e.message;
} catch (String err) {
Konsol:Print("caught file error: ${err}");
}
// ── Custom Exception hierarchy ────────────────────────────────────────────────
Konsol:Print("--- exception hierarchy ---");
Class:Create(NetworkException extends Exception) {
Var:Number statusCode;
function initNet(Number code, String msg) {
type = "NetworkException";
statusCode = code;
message = msg;
}
function toString() : String {
return "[" + type + " " + statusCode + "] " + message;
}
}
Class:Create(TimeoutException extends NetworkException) {
Var:Number timeoutMs;
function initTimeout(Number ms) {
type = "TimeoutException";
timeoutMs = ms;
message = "request timed out after " + ms + "ms";
statusCode = 408;
}
}
Class:NetworkException ne;
ne.initNet(404, "endpoint not found");
Var:String neStr;
neStr = ne.toString();
Konsol:Print("NetworkException toString = ${neStr}");
Var:Boolean neIsNet;
neIsNet = ne.isInstanceOf("NetworkException");
Konsol:Print("isInstanceOf NetworkException = ${neIsNet}");
Var:Boolean neIsExc;
neIsExc = ne.isInstanceOf("Exception");
Konsol:Print("isInstanceOf Exception = ${neIsExc}");
Class:TimeoutException te;
te.initTimeout(5000);
Var:String teStr;
teStr = te.toString();
Konsol:Print("TimeoutException toString = ${teStr}");
Var:Boolean teIsTimeout;
teIsTimeout = te.isInstanceOf("TimeoutException");
Konsol:Print("isInstanceOf TimeoutException = ${teIsTimeout}");
Var:Boolean teIsNet;
teIsNet = te.isInstanceOf("NetworkException");
Konsol:Print("isInstanceOf NetworkException = ${teIsNet}");
Var:Boolean teIsExc;
teIsExc = te.isInstanceOf("Exception");
Konsol:Print("isInstanceOf Exception = ${teIsExc}");
Var:Boolean teIsObj;
teIsObj = te.isInstanceOf("Object");
Konsol:Print("isInstanceOf Object = ${teIsObj}");
Var:Boolean teIsFile;
teIsFile = te.isInstanceOf("FileException");
Konsol:Print("isInstanceOf FileException = ${teIsFile}");
// Catch exceptions by message regardless of subtype
Konsol:Print("--- catch any exception ---");
try {
Class:TimeoutException t;
t.initTimeout(3000);
throw t.message;
} catch (String err) {
Konsol:Print("caught timeout: ${err}");
}