PROLOGUE
I'm using async-graphql and I have hundreds of resolvers and for each resolver I would like to trace all the possible errors.
In each method of my app I'm using anyhow::{Error}
.
Right now I have code similar to this for each resolver:
#[Object]
impl MutationRoot {
async fn player_create(&self, ctx: &Context<'_>, input: PlayerInput) -> Result<Player> {
let services = ctx.data_unchecked::<Services>();
let player = services
.player_create(input)
.await?;
Ok(player)
}
}
So I thought about using the below code (note the added line with .map_err()
):
#[Object]
impl MutationRoot {
async fn player_create(&self, ctx: &Context<'_>, input: PlayerInput) -> Result<Player> {
let services = ctx.data_unchecked::<Services>();
let player = services
.player_create(input)
.await
.map_err(errorify)?;
Ok(player)
}
}
fn errorify(err: anyhow::Error) -> async_graphql::Error {
tracing::error!("{:?}", err);
err.into()
}
Now the error is traced along with all the error chain:
ERROR example::main:10: I'm the error number 4
Caused by:
0: I'm the error number 3
1: I'm the error number 2
2: I'm the error number 1
in example::async_graphql
QUESTION 1
Is there a way to avoid the .map_err()
on each resolver?
I would like to use the ?
alone.
Should I use a custom error?
Can we have a global "hook"/callback/fn to call on each error?
QUESTION 2
As you can see above the chain of the error is the inverse.
In my graphql response I'm getting as message
the "I'm the error number 4" but I need to get the "I'm the error number 2" instead.
The error chain is created using anyhow
like this:
- main.rs: returns error with
.with_context(|| "I'm the error number 4")?
-
- call
fn player_create()
ingraphql.rs
: returns with.with_context(|| "I'm the error number 3")?
- call
-
-
- call
fn new_player()
indomain.rs
: returns with.with_context(|| "I'm the error number 2")?
- call
-
-
-
-
- call
fn save_player()
indatabase.rs
: returns with.with_context(|| "I'm the error number 1")?
- call
-
-
How can I accomplish this?
I'm really new to Rust. I come from Golang where I was using a struct like:
type Error struct {
error error
public_message string
}
chaining it easily with:
return fmt.Errorf("this function is called but the error was: %w", previousError)
How to do it in Rust?
Do I necessarily have to use anyhow
?
Can you point me to a good handling error tutorial/book for applications?
Thank you very much.