use carla::{
CarlaError,
client::{ActorBase, Client},
geom::{Location, Rotation, Transform},
};
use std::time::Duration;
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("=== CARLA Error Handling Patterns Demo ===\n");
let client = Client::connect("127.0.0.1", 2000, None)?;
let mut world = client.world()?;
println!("Connected to CARLA server\n");
demo_resource_errors(&mut world);
demo_operation_errors_with_retry(&mut world);
demo_validation_errors(&mut world);
demo_error_classification();
println!("\n=== Error handling demo complete ===");
Ok(())
}
fn demo_resource_errors(world: &mut carla::client::World) {
println!("--- Demo 1: Resource Not Found Errors ---");
match world.actor_builder("vehicle.nonexistent.model") {
Ok(_) => println!("Found blueprint (unexpected)"),
Err(e) => {
if e.is_not_found() {
println!("✓ Resource not found error: {}", e);
println!("✓ Error is retriable: {}", e.is_retriable());
println!("Trying fallback blueprint...");
match world.actor_builder("vehicle.tesla.model3") {
Ok(_) => println!("✓ Fallback blueprint found successfully"),
Err(e) => println!("Fallback also failed: {}", e),
}
}
}
}
println!();
}
fn demo_operation_errors_with_retry(world: &mut carla::client::World) {
println!("--- Demo 2: Operation Errors with Retry ---");
let spawn_points = world
.map()
.expect("API call failed")
.recommended_spawn_points()
.expect("API call failed");
let spawn_point = match spawn_points.get(0) {
Some(p) => p.clone(),
None => {
println!("No spawn points available");
println!();
return;
}
};
let blueprint = match world
.blueprint_library()
.expect("API call failed")
.find("vehicle.tesla.model3")
.expect("API call failed")
{
Some(bp) => bp,
None => {
println!("Blueprint not found");
println!();
return;
}
};
match spawn_with_retry(world, &blueprint, &spawn_point, 3) {
Ok(actor) => {
println!("✓ Successfully spawned actor: ID {}", actor.id());
let _ = actor.destroy().expect("API call failed");
}
Err(e) => {
println!("✗ Failed to spawn after retries: {}", e);
}
}
println!();
}
fn spawn_with_retry(
world: &mut carla::client::World,
blueprint: &carla::client::ActorBlueprint,
transform: &Transform,
max_retries: u32,
) -> Result<carla::client::Actor, CarlaError> {
let mut attempts = 0;
loop {
attempts += 1;
println!("Spawn attempt {}/{}...", attempts, max_retries);
match world.spawn_actor(blueprint, transform) {
Ok(actor) => {
println!("✓ Spawn successful on attempt {}", attempts);
return Ok(actor);
}
Err(e) => {
if e.is_retriable() && attempts < max_retries {
println!(" Retriable error: {}. Retrying...", e);
std::thread::sleep(Duration::from_millis(100));
continue;
} else {
println!(" Non-retriable error or max retries reached");
return Err(e);
}
}
}
}
}
fn demo_validation_errors(world: &mut carla::client::World) {
println!("--- Demo 3: Validation Errors ---");
match world
.actor_builder("vehicle.tesla.model3")
.and_then(|builder| builder.set_attribute("invalid_attribute", "some_value"))
{
Ok(_) => println!("Attribute set (unexpected)"),
Err(e) => {
if e.is_validation_error() {
println!("✓ Validation error detected: {}", e);
println!(" This indicates invalid input/configuration");
}
}
}
let spawn_transform = Transform {
location: Location::new(0.0, 0.0, 100.0),
rotation: Rotation {
pitch: 0.0,
yaw: 0.0,
roll: 0.0,
},
};
match world
.actor_builder("vehicle.tesla.model3")
.and_then(|builder| builder.spawn_sensor(spawn_transform))
{
Ok(_) => println!("Spawned sensor (unexpected)"),
Err(e) => {
if e.is_validation_error() {
println!("✓ Type mismatch validation error: {}", e);
}
}
}
println!();
}
fn demo_error_classification() {
println!("--- Demo 4: Error Classification ---");
let errors = vec![
"connection timeout",
"blueprint not found",
"spawn failed",
"invalid configuration",
];
for error_msg in errors {
println!("Classifying: \"{}\"", error_msg);
println!(" (In real code, use error.is_*() methods)");
}
println!("\nCarlaError helper methods:");
println!(" - is_connection_error() - Network/server issues");
println!(" - is_timeout() - Operation timeout");
println!(" - is_not_found() - Resource doesn't exist");
println!(" - is_validation_error() - Invalid input");
println!(" - is_operation_error() - Operation failed");
println!(" - is_map_error() - Map/waypoint issues");
println!(" - is_sensor_error() - Sensor issues");
println!(" - is_internal_error() - Internal/FFI errors");
println!(" - is_retriable() - Can be retried");
println!();
}