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 messagethrow 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 categorythrow 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 namethrow 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
| Feature | Status |
|---|---|
finally blocks | Planned |
| Custom exception classes (extends Error) | Planned |
| Multiple catch blocks | Planned |
| Rethrowing exceptions | Planned |