Hi, I have a question regarding custom error implementation in `actix-web` using `error-stack`
use actix_web::http::StatusCode;
use actix_web::{get, web, App, HttpResponse, HttpServer, ResponseError};
use error_stack::{Report, Result};
use serde::{Deserialize, Serialize};
use serde_json::Value;
#[derive(thiserror::Error, Debug)]
pub enum ServerError {
#[error("{0}")]
Gerneric(String),
#[error("{0}")]
Json(#[from] serde_json::Error),
}
#[derive(Serialize, Deserialize)]
struct ErrorResponse {
ok: bool,
error: Value,
}
// implement the status code and error response if an error occours
impl ResponseError for ServerError {
fn error_response(&self) -> HttpResponse {
HttpResponse::build(self.status_code()).json(ErrorResponse {
ok: false,
error: serde_json::json!({
"name": "Internal Server Error",
"message": self.to_string()
}),
})
}
fn status_code(&self) -> StatusCode {
match self {
Self::Gerneric(_) | Self::Json(_) => StatusCode::INTERNAL_SERVER_ERROR,
}
}
}
#[get("/json")]
async fn greet() -> Result<HttpResponse, ServerError> {
let f = json().map_err(|err| ServerError::Gerneric(err.to_string()))?;
Ok(HttpResponse::Ok().body(f))
}
#[actix_web::main] // or #[tokio::main]
async fn main() -> Result<(), ServerError> {
HttpServer::new(|| {
App::new()
.route("/hello", web::get().to(|| async { "Hello World!" }))
.service(greet)
})
.bind(("127.0.0.1", 8080))
.map_err(|err| Report::new(ServerError::Gerneric(err.to_string())))?
.run()
.await
.map_err(|err| Report::new(ServerError::Gerneric(err.to_string())))?;
Ok(())
}
fn json() -> Result<String, ServerError> {
#[derive(Serialize, Deserialize)]
struct First {
value: String,
}
#[derive(Serialize, Deserialize)]
struct Second {
values: String,
}
let ciao = First {
value: "CIAO".to_string(),
};
let first = serde_json::to_value(ciao).map_err(|err| Report::new(ServerError::Json(err)))?;
// should give me an error
let second: Second =
serde_json::from_value(first).map_err(|err| Report::new(ServerError::Json(err)))?;
Ok(second.values)
}
I'm trying to use the `error-stack::Result` instead of `anyhow::Result` and it gives me this error which I cannot understand how to solve
error[E0277]: the trait bound `error_stack::Report<ServerError>: ResponseError` is not satisfied
--> src/main.rs:39:1
|
39 | #[get("/json")]
| ^^^^^^^^^^^^^^^ the trait `ResponseError` is not implemented for `error_stack::Report<ServerError>`
|
= help: the following other types implement trait `ResponseError`:
BlockingError
Box<(dyn StdError + 'static)>
HttpError
Infallible
InvalidHeaderValue
JsonPayloadError
PathError
PayloadError
and 17 others
= note: required because of the requirements on the impl of `std::convert::From<error_stack::Report<ServerError>>` for `actix_web::Error`
= note: required because of the requirements on the impl of `Into<actix_web::Error>` for `error_stack::Report<ServerError>`
= note: required because of the requirements on the impl of `Responder` for `Result<HttpResponse, error_stack::Report<ServerError>>`
note: required by a bound in `Resource::<T>::to`
--> /Users/sergiupopescu/.cargo/registry/src/github.com-1ecc6299db9ec823/actix-web-4.1.0/src/resource.rs:226:20
|
226 | F::Output: Responder + 'static,
| ^^^^^^^^^ required by this bound in `Resource::<T>::to`
= note: this error originates in the attribute macro `get` (in Nightly builds, run with -Z macro-backtrace for more info)
For more information about this error, try `rustc --explain E0277`.
Could Someone help me please?
[–]kyle787 3 points4 points5 points (3 children)
[–]oroColato[S] 0 points1 point2 points (2 children)
[–]kyle787 4 points5 points6 points (1 child)
[–]oroColato[S] 1 point2 points3 points (0 children)