async-graphql: How to make Logger extension to utilize Debug implementation for my errors instead of Display?
Hello!
Recently I’ve started using async-graphql
and it feels really great so far. Thank you for working on it!
When I use logger extension in my logs I see strings which come from Display
trait implementation for my errors. From my perspective Display
represents what consumers/users should see and Debug
represents what developers should see when they look at the error.
There are cases where I want to hide some details from users/consumers and just output “unexpected error”, but I would like to have full details in the logs for debugging purposes.
How can I achieve that?
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 1
- Comments: 32 (3 by maintainers)
Commits related to this issue
- Add `Failure` type. #671 — committed to async-graphql/async-graphql by sunli829 3 years ago
- Rework Failure #671 — committed to async-graphql/async-graphql by sunli829 3 years ago
- Rework Failure2 #671 — committed to async-graphql/async-graphql by sunli829 3 years ago
- Rework Failure 3 #671 — committed to async-graphql/async-graphql by sunli829 3 years ago
- Rework Failure 3 #671 — committed to async-graphql/async-graphql by sunli829 3 years ago
- Change the signature of the `connection::query` function to allow the callback to use any type that implements `Into<Error>`. #671 — committed to async-graphql/async-graphql by sunli829 3 years ago
Haha, I’m also looking forward to the specialization feature 😁! I will try to take some time to look into what you did tonight, I have also some ideas to write for the v3!
I will definitely be interested to contribute to the package in some way. Maybe improving docs is a possible option.
Currently I am working on a project and trying to collect my thoughts around the library APIs and the ways things are not working that well for me. Will try to wrap all the experiences up and share, once I am ready. Hopefully we can take things forward from that point 😃
Since
Error
no longer implementsDisplay
(I just found out), there will be no more type conflicts, so I deletedResolverError
. @Miaxos @gyzerokhttps://github.com/async-graphql/async-graphql/blob/d33c9ce88bd7bc2f69332f9b415ffd139c84189d/tests/error_ext.rs#L80
It looks pretty good now!
It is still a breaking change, so I support it in
v3.0
.This problem is not as easy to solve as it seems, and I need to think about it. 😁
Hello @Miaxos and thank you for the detailed response!
I think I might have a slightly different idea. Let me outline it a bit later today/tomorrow so we can compare them. I am pretty new to Rust, but maybe it’s my opportunity to dig a bit deeper into
async-graphql
and make a useful contribution 🤷I added
Error::new_with_source
method inv3
, so theResolverError
type is no longer needed.I can’t design a more convenient API without generic specialization, so I can only keep
ResolverError
. 😒I just think
ResolverError
is not a good name. 🙂It seems also that
query
function which helps to create cursor connections is forced to returnasync_graphql::Result
. So I am not sure how to use it with my custom error types.Thank you, gonna try it now 😄 And I actually found a case why the order of fields in the response do matter. The version before that fix breaks my tests. So your update is right on time!
Currently I am at my early stages of learning Rust. And most of the stuff I am doing is based on Zero to Production book.
Author is using
actix-web
there so I am using it as well. However I’ve decided to diverge a bit and use GraphQL instead of writing REST. While working with your library simple simple and fun, I believe that enough of additional learning complexity for me now.Perhaps once I feel confident with all the things I have now on my place I can give a try to
poem
. Thank you for suggestion!I’m done, now the only trouble is that you need to manually convert your error type to
Failure
, like the following:Get concrete error from
ServerError
:Here is the test:
https://github.com/async-graphql/async-graphql/blob/d62aca805269b40f2093042d7791188d24fe3074/tests/error_ext.rs#L80
Because Rust does not support generic specialization, this
Failure
type is required.Your proposal
The downside I see in your proposal is boilerplate. Let’s imagine that each my resolver has it’s own specific error type
enum Failure {}
. Then for each such type I need to implementResolverError
trait.Which in a way will be almost exactly (but with traits) what I am currently doing with functions
And what I actually want is to get rid of this repetition + make sure that you can’t forget to log errors correctly while writing new code.
My proposal
My suggestion is to focus around saving the initial error so one can use it later in the pipeline. For example I would be able to easily achieve what I want by writing custom
Logger
implementation if only I could get raw error.What if instead of converting errors from
async_graphql::Error
toasync_graphql::ServerError
before passing response to schema extension we would do it only after? This way developers would be able to write some custom logic for operating on errors before they get converted and sent to the client.To do this I would change
async_graphql::Error
like so:And then later in the logger I could use
source
to do whatever I like.