Error type conversions

Hi, I'm new to Rustand stuck at converting one error type to another.

use actix_web::{middleware, post, web, App, Error, HttpResponse, HttpServer};
use my::Model
use my::ModelRequest

async fn predict(
    model: web::Data<Arc<Model>>,
    data: web::Json<ModelRequest>,
) -> anyhow::Result<HttpResponse> {
    let res = web::block(move || {
        model.predict(data)
    })
    .await
    .map_err(|e| HttpResponse::InternalServerError().body(e.to_string()))?; // e has type BlockingError<Box<dyn Error + Send + Sync>>
    Ok(HttpResponse::Ok()
        .content_type("application/json")
        .json(res))
}

model.predict(data) produces a std::result::Result<T, Box<dyn std::error::Error + Send + Sync>> which is defined in a library.
Now the compiling error is

the trait bound `actix_web::HttpResponse: std::error::Error` is not satisfied
required because of the requirements on the impl of `std::convert::From<actix_web::HttpResponse>` for `anyhow::Error`
required by `std::convert::From::from`

it is not clear to me which error needs to be converted to which error type.

The conversion that failed is HttpResponse → anyhow::Error. It tried to perform this conversion because the return value created in the map_err is an HttpResponse.

It sounds like you should change the code to return something like this:

use actix_web::{middleware, post, web, App, Error, HttpResponse, HttpServer};
use my::Model
use my::ModelRequest

async fn predict(
    model: web::Data<Arc<Model>>,
    data: web::Json<ModelRequest>,
) -> HttpResponse {
    let res = web::block(move || {
        model.predict(data)
    }).await;
    
    match res {
        Ok(res) => HttpResponse::Ok()
            .content_type("application/json")
            .json(res),
        Err(e) => HttpResponse::InternalServerError()
            .body(e.to_string()),
    }
}

because even if the prediction failed, you still successfully created an HttpResponse object.

1 Like

Thanks for your explanation!
I realize that I can also make the return type std::result::Result<HttpResponse, actix_web::Error>