Async function with tokio::main , await error handling advice

Hi,
I'm working on a project where i'm handling tokio and async. My code works, but i do need feel confident in the error handling i'm doing since it is my first time working with async in rust & with tokio since each function return is just made with .await? and i can't find good ressources to deepen my understanding in this.
Here is my main loop, run in my async fn with tokio::main

loop {
        // in the main receiver we will keep it clean
        // we need : cpu ram memory network disks ressources sending and caching
        // it will be fixed with flags and config after but for now, just try to be exhaustive while keeping things apart
        if collector_agent.debug_mode {
            collector_agent.print_system_values();
            collector_agent.print_networks_values();
            collector_agent.print_disks_values();
            collector_agent.refresh_all_metrics();
        }

        if collector_agent.is_working {
            if collector_agent.config.resources.cpu {
                communicator_agent
                    .send_cpu(collector_agent.system_agent.prepare_cpu_payload())
                    .await?;
            }
            if collector_agent.config.resources.disk {
                communicator_agent
                    .send_disks(collector_agent.prepare_disks_payload())
                    .await?;
            }
            if collector_agent.config.resources.memory {
                communicator_agent
                    .send_memory(collector_agent.system_agent.prepare_memory_payload())
                    .await?;
            }
            if collector_agent.config.resources.network {
                communicator_agent
                    .send_network(collector_agent.prepare_network_payload())
                    .await?;
            }
            if collector_agent.config.resources.processes {
                communicator_agent
                    .send_processes(collector_agent.system_agent.prepare_processes_payload())
                    .await?;
            }
        }
        // we can switch it up, it's juste the minimum time interval to get a correct cpu evolution
        // don't know where to put it rn
        tokio::time::sleep(
            sysinfo::MINIMUM_CPU_UPDATE_INTERVAL.max(Duration::from_millis(
                collector_agent.config.general.refresh_rate_ms,
            )),
        )
        .await;
        // for debugging rn, just a little more delay to read, now parsed from config file
    }

.await and ? are too very different things which do very different jobs.

.await "awaits" a future, which in overly simplified (and thus technicallly incorrect) terms means that it runs the function to completion. it's not very important as far as error handling is concerned.

basically my_sync_function() is mostly the same as my_async_function().await.

the ? operator is what matters for error handling. the ? operator takes a fallible value, like a Result, and tries to extract the successful value from it. if it succeeds, the execution continues, but if it doesn't, it exits from the current function with the error it got.
so every time you write ?, you basically write "if you got an error, return from this function with the error you got"

here is some doc on ? : ? - Rust By Example

Right now the function enclosing your loop will return an error if any of these steps marked with ? fail. Is that what you want or do you have a more sophisticated plan for error recovery?

If you're okay with failing immediately, depending on your error type, you might not get any useful extra information, e.g. the fact that it was this function that called a failing send_cpu. Is that okay or do you want to attach extra information to the error?

1 Like

Yes, for now error is failling, but i would like to know how to do some more advanced error recovery like logging and retrying to send the payload + sending another payload containing the error for debugging purpose. While i think i know how to handle it in a sync rust function, i don't know how to handle the problem correctly to get this type of error handling on an async function using tokio so that it doesn't get blocking / generating more error ... Thank you for the answers