0

Is there a way to handle errors inside main method in actix-web?

I have the following code, as you can see there's three places in that function that can panic: the reference to the DATABASE_URL environment variable, the creation of the connection pool and the initialization of the template engine (tera).

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    dotenv().ok();
    let database_url = std::env::var("DATABASE_URL").expect("DATABASE_URL must be set.");
    let manager = ConnectionManager::<PgConnection>::new(database_url);
    let pool = Pool::builder().build(manager).expect("Failed to create connection pool.");

    HttpServer::new(move || {
        let tera = Tera::new("templates/**/*").unwrap();
        App::new()
            .data(pool.clone())
            .data(tera)
            .route("/", web::get().to(index))
    })
    .bind("127.0.0.1:8000")?
    .run()
    .await
}

So, I tried to change the return type on that function and use a previously defined Enum in order to handle those errors:

async fn main() -> Result<HttpServer, ServerError> {
    dotenv().ok();
    let database_url = std::env::var("DATABASE_URL")?;
    let manager = ConnectionManager::<PgConnection>::new(database_url);
    let pool = Pool::builder().build(manager)?;

    HttpServer::new(move || {
        let tera = Tera::new("templates/**/*")?;
        App::new()
            .data(pool.clone())
            .data(tera)
            .route("/", web::get().to(index))
    })
    .bind("127.0.0.1:8000")?
    .run()
    .await
}

But the compiler shows this message:

[Running 'cargo run']

error[E0107]: missing generics for struct `HttpServer`
    |
    | async fn main() -> Result<HttpServer, ServerError> {
    |                           ^^^^^^^^^^ expected 4 type arguments
    |

note: struct defined here, with 4 type parameters: `F`, `I`, `S`, `B`

    |
    | pub struct HttpServer<F, I, S, B>
    |            ^^^^^^^^^^ -  -  -  -
help: use angle brackets to add missing type arguments
    |
    | async fn main() -> Result<HttpServer<F, I, S, B>, ServerError> {
    |                                     ^^^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0107`.
error: could not compile

What's the best course of action that I can follow here? Should I handle this kind of errors within the main method?

zuko
  • 13
  • 3
  • Will main method need to return a `Ok(HttpServer)`? If not you can try making main method to return `Result<(), ServerError>` I think. – 0x00A5 May 24 '21 at 14:31
  • Why don't you just change your first, original method to return `std::result::Result<(), ServerError>`? Note that `std::io::Result` is actually an alias/shortcut for `std::result::Result`, so all this would do is change the error type from `std::io::Error` to `ServerError`, which I think is what you were trying to do. The name of `std::io::Result` always bothers me, I think it should be something like `std::io::IoResult` to be clear... (same idea with `IoError`); it's slightly different from a normal `std::result::Result` since you can't specify a custom error type. – Coder-256 May 25 '21 at 01:52

0 Answers0