Skip to content

Exception Handling

Zeus provides exception handling with try, catch, and throw for robust error management.

The Error Class

Zeus has a built-in Error class that serves as the base for all exceptions:

// Create and throw an error with name and message
throw new Error("ValidationError", "Invalid input value");

The Error class has two properties:

  • name - The type/category of the error (e.g., “ValidationError”, “NetworkError”)
  • message - A detailed description of what went wrong

Try-Catch Blocks

Handle runtime errors gracefully with try-catch:

function divide(a: i32, b: i32): i32 {
if (b == 0) {
throw new Error("DivisionError", "Division by zero");
}
return a / b;
}
function main(): i32 {
try {
let result: i32 = divide(10, 0);
return result;
} catch (e: Error) {
log("Caught " + e.name + ": " + e.message);
return -1;
}
}

Throw Statement

Use throw to raise an exception:

function validateAge(age: i32): void {
if (age < 0) {
throw new Error("ValidationError", "Age cannot be negative");
}
if (age > 150) {
throw new Error("ValidationError", "Age seems unrealistic");
}
}

Built-in Exceptions

Zeus automatically throws exceptions in certain error conditions:

NullReferenceException

Thrown when accessing a property on a null object:

class Person {
name: string;
constructor(name: string) {
this.name = name;
}
}
function main(): i32 {
let person: Person; // null by default
log(person.name); // Throws NullReferenceException
return 0;
}

IndexOutOfBoundsException

Thrown when accessing an array with an invalid index:

function main(): i32 {
let arr: i32[] = new i32[];
arr.push(10);
arr.push(20);
let value: i32 = arr[5]; // Throws IndexOutOfBoundsException
return value;
}

Stack Traces

When an exception is not caught, Zeus displays a detailed stack trace:

Unhandled Exception: Division by zero
Stack Trace:
0: divide
at example.zs:3
2 | if (b == 0) {
> 3 | throw new Error("Division by zero");
4 | }
1: main
at example.zs:10
9 | try {
> 10 | let result: i32 = divide(10, 0);
11 | return result;

Catching Exceptions

The catch block receives the exception object:

function main(): i32 {
try {
throw new Error("TestError", "Something went wrong");
} catch (e: Error) {
// Access the error name and message
log("Caught " + e.name + ": " + e.message);
return 1;
}
return 0;
}

Best Practices

Descriptive Error Names

Use meaningful error names to categorize errors:

// Good - clear error category
throw new Error("ValidationError", "Invalid email format: missing @ symbol");
throw new Error("NetworkError", "Connection timeout after 30 seconds");
throw new Error("FileError", "Cannot read file: permission denied");
// Less helpful - generic name
throw new Error("Error", "Something went wrong");

Early Validation

Validate inputs early and throw descriptive errors:

function processOrder(quantity: i32, price: f64): f64 {
if (quantity <= 0) {
throw new Error("ValidationError", "Quantity must be positive");
}
if (price < 0.0) {
throw new Error("ValidationError", "Price cannot be negative");
}
return price * quantity;
}

Graceful Degradation

Handle errors gracefully when possible:

function safeGetElement(arr: i32[], index: i32): i32 {
try {
return arr[index];
} catch (e: Error) {
log("Caught " + e.name + ", returning default value");
return 0;
}
}

Coming Soon

FeatureStatus
finally blocksPlanned
Custom exception classes (extends Error)Planned
Multiple catch blocksPlanned
Rethrowing exceptionsPlanned

Next

Modules →