NAME
Sidef::Types::Block::Try - Exception handling block in Sidef
DESCRIPTION
This class implements the try-catch exception handling construct in Sidef. The Try block provides a mechanism to execute code that may throw errors or exceptions, and gracefully handle those errors without causing the program to terminate unexpectedly.
A try-catch construct allows you to:
Execute potentially unsafe or error-prone code
Catch and handle exceptions that occur during execution
Maintain program flow even when errors occur
Provide error recovery mechanisms
SYNOPSIS
Basic try-catch usage:
try {
# Code that might throw an exception
var result = (10 / 0)
}
catch { |error|
say "Error occurred: #{error}"
}
Try-catch with specific error handling:
try {
var file = File("nonexistent.txt").open_r
var content = file.slurp
}
catch { |err|
say "Failed to read file: #{err}"
}
Nested try-catch blocks:
try {
try {
# Inner operation
die "Inner error"
}
catch { |e|
say "Caught inner: #{e}"
die "Outer error"
}
}
catch { |e|
say "Caught outer: #{e}"
}
METHODS
try
self.try(block)
Executes the provided block of code within a protected context. If an exception occurs during the execution of the block, control is transferred to the associated catch block rather than terminating the program.
Parameters:
block- A Block object containing the code to execute
Returns: The Try object (for method chaining with catch)
Example:
var result = try {
var x = some_risky_operation()
x * 2
}
catch { |e|
say "Operation failed: #{e}"
nil # Return nil on error
}
catch
self.catch(block)
Defines the exception handler that will be executed if an exception occurs in the try block. The catch block receives the exception/error object as its parameter, which can be used to inspect the error details.
Parameters:
block- A Block object that handles the exception. The block receives the error object as its first parameter.
Returns: The result of either the try block (if successful) or the catch block (if an exception occurred)
Example:
try {
var num = Number("not_a_number")
}
catch { |error|
say "Conversion failed: #{error}"
0 # Return default value
}
USAGE NOTES
Exception Propagation
If a catch block is not provided, or if the catch block itself throws an exception, the error will propagate up the call stack to the next outer try-catch block or cause the program to terminate.
Return Values
Both the try and catch blocks can return values. The last expression in whichever block completes will be the return value of the entire try-catch construct:
var result = try {
42 # Returned if successful
}
catch {
0 # Returned if exception occurs
}
Multiple Catches
While Sidef doesn't support multiple catch blocks for different exception types in a single construct, you can handle different error types within a single catch block using conditional logic:
try {
risky_operation()
}
catch { |e|
given (e) {
when (e ~~ /FileError/) {
say "File error: #{e}"
}
when (e ~~ /NetworkError/) {
say "Network error: #{e}"
}
default {
say "Unknown error: #{e}"
}
}
}
Throwing Exceptions
You can explicitly throw exceptions using the die function:
try {
die "Something went wrong!"
}
catch { |e|
say "Caught: #{e}"
}
COMMON PATTERNS
Resource Cleanup
While Sidef doesn't have a finally clause, you can ensure cleanup by placing cleanup code after the try-catch block:
var file = nil
try {
file = File("data.txt").open_r
# Process file
}
catch { |e|
say "Error: #{e}"
}
# Cleanup always happens
file && file.close
Error Logging with Re-throw
You can log an error and then re-throw it:
try {
critical_operation()
}
catch { |e|
say "Error logged: #{e}"
die e # Re-throw the exception
}
Default Values on Error
Provide default values when operations fail:
func safe_divide(a, b) {
try {
a / b
}
catch {
0 # Return 0 on division by zero
}
}
SEE ALSO
Sidef::Types::Block::Block - Base block type
die - Function to throw exceptions
eval - Evaluate code in a string (also provides exception handling)
EXAMPLES
Example 1: Safe File Reading
func read_config(filename) {
try {
var file = File(filename).open_r
var content = file.slurp
file.close
return content
}
catch { |e|
say "Warning: Could not read #{filename}: #{e}"
return ""
}
}
Example 2: Parsing with Error Handling
func parse_number(str) {
try {
return Number(str)
}
catch { |e|
say "Invalid number format: '#{str}'"
return nil
}
}
var nums = ["42", "abc", "123", "xyz"].map { |s|
parse_number(s)
}.grep { defined(_) }
say nums # [42, 123]
Example 3: Retry Logic
func fetch_with_retry(url, max_attempts = 3) {
var attempts = 0
loop {
try {
return fetch_url(url)
}
catch { |e|
attempts++
if (attempts >= max_attempts) {
die "Failed after #{attempts} attempts: #{e}"
}
say "Attempt #{attempts} failed, retrying..."
}
}
}