///|
test "basic error handling" {
fn divide(a : Int, b : Int) -> Int raise {
if b == 0 {
raise Failure::Failure("Division by zero")
} else {
a / b
}
}
// Successful operation
let result1 = try! divide(10, 2)
inspect(result1, content="5")
// Handle error with try/catch/noraise
try divide(10, 0) catch {
e => debug_inspect(e, content="Failure(\"Division by zero\")")
} noraise {
_ => fail("expected error")
}
}///|
suberror ValidationError {
ValidationError(String)
}
///|
suberror NetworkError {
NetworkError(String)
}
///|
test "custom errors" {
fn validate_email(email : String) -> String raise ValidationError {
if email.length() > 5 { // Simple validation without string methods
email
} else {
raise ValidationError("Invalid email format")
}
}
fn fetch_data(url : String) -> String raise NetworkError {
if url.length() > 10 { // Simple validation
"data"
} else {
raise NetworkError("Invalid URL")
}
}
// Test validation error
try validate_email("short") catch {
_ => ()
} noraise {
_ => fail("expected validation error")
}
// Test network error
try fetch_data("short") catch {
_ => ()
} noraise {
_ => fail("expected network error")
}
}///|
priv suberror MyError {
MyError(Int)
} derive(ToJson)
///|
test "error display and json" {
let error : Error = MyError(42)
// Error can be displayed as string
let error_string = error.to_string()
inspect(error_string.length() > 0, content="true")
// Error can be converted to JSON
let error_json = error.to_json()
@debug.debug_inspect(
error_json,
content="Array([String(\"MyError\"), Number(42)])",
)
}///|
suberror ParseError {
ParseError(String)
}
///|
suberror FileError {
FileError(String)
}
///|
test "error propagation" {
fn parse_number(s : String) -> Int raise ParseError {
if s == "42" {
42
} else {
raise ParseError("Invalid number: " + s)
}
}
fn read_and_parse(content : String) -> Int raise {
parse_number(content) catch {
ParseError(msg) => raise FileError("Parse failed: " + msg)
}
}
// Success case
let result1 = try! read_and_parse("42")
inspect(result1, content="42")
// Error propagation
try read_and_parse("invalid") catch {
_ => ()
} noraise {
_ => fail("expected error propagation")
}
}///|
suberror ResourceError {
ResourceError(String)
}
///|
test "resource management" {
fn risky_operation() -> String raise ResourceError {
raise ResourceError("Something went wrong")
}
// Simple resource management pattern
fn use_resource() -> String raise {
// Acquire resource (simulated)
risky_operation() catch {
ResourceError(_) =>
// Cleanup happens here
raise Failure::Failure("Operation failed after cleanup")
}
}
try use_resource() catch {
_ => ()
} noraise {
_ => fail("expected resource error")
}
}///|
suberror ConfigError {
ConfigError(String)
}
///|
suberror DatabaseError {
DatabaseError(String)
}
///|
test "error composition" {
fn load_config() -> String raise ConfigError {
if true {
"config_data"
} else {
raise ConfigError("Config not found")
}
}
fn connect_database(config : String) -> String raise DatabaseError {
if config == "config_data" {
"connected"
} else {
raise DatabaseError("Invalid config")
}
}
fn initialize_app() -> String raise {
let config = load_config() catch {
ConfigError(msg) => raise Failure::Failure("Config error: " + msg)
}
let db = connect_database(config) catch {
DatabaseError(msg) => raise Failure::Failure("Database error: " + msg)
}
"App initialized with " + db
}
let app_result = try! initialize_app()
inspect(app_result, content="App initialized with connected")
}fn Error::to_string(self : Error) -> StringInstall
Installed by default