1use async_graphql::ErrorExtensions;
2use thiserror::Error;
3
4#[derive(Error, Debug)]
5#[non_exhaustive]
6pub enum GraphQLError {
7 #[error("Config error: {0}")]
8 Config(String),
9
10 #[error("Schema parse error at {location}: {message}")]
11 SchemaParse { message: String, location: String },
12
13 #[error("Schema build error: {0}")]
14 SchemaBuild(String),
15
16 #[error("Database error: {0}")]
17 Database(String),
18
19 #[error("Not found: {message}")]
20 NotFound { message: String },
21
22 #[error("Duplicate key: {message}")]
23 DuplicateKey { message: String },
24
25 #[error("Pagination error: {0}")]
26 Pagination(String),
27
28 #[error("Unauthorized: {0}")]
29 Unauthorized(String),
30
31 #[error("Forbidden: {0}")]
32 Forbidden(String),
33
34 #[error("Internal error: {0}")]
36 Internal(String),
37}
38
39impl GraphQLError {
40 pub fn into_graphql_error(self) -> async_graphql::Error {
42 let message = self.to_string();
43 match &self {
44 GraphQLError::NotFound { .. } => {
45 async_graphql::Error::new(message).extend_with(|_, extensions| {
46 extensions.set("code", "NOT_FOUND");
47 })
48 }
49 GraphQLError::Unauthorized(_) => {
50 async_graphql::Error::new(message).extend_with(|_, extensions| {
51 extensions.set("code", "UNAUTHORIZED");
52 })
53 }
54 GraphQLError::Forbidden(_) => {
55 async_graphql::Error::new(message).extend_with(|_, extensions| {
56 extensions.set("code", "FORBIDDEN");
57 })
58 }
59 GraphQLError::DuplicateKey { .. } => {
60 async_graphql::Error::new(message).extend_with(|_, extensions| {
61 extensions.set("code", "DUPLICATE_KEY");
62 })
63 }
64 GraphQLError::Pagination(_) => {
65 async_graphql::Error::new(message).extend_with(|_, extensions| {
66 extensions.set("code", "INVALID_CURSOR");
67 })
68 }
69 GraphQLError::Database(_)
70 | GraphQLError::Internal(_)
71 | GraphQLError::SchemaParse { .. }
72 | GraphQLError::SchemaBuild(_)
73 | GraphQLError::Config(_) => {
74 async_graphql::Error::new("Internal server error")
75 }
76 }
77 }
78}
79
80impl From<async_graphql::Error> for GraphQLError {
81 fn from(e: async_graphql::Error) -> Self {
82 GraphQLError::Internal(e.message)
83 }
84}
85
86impl From<mongodb::error::Error> for GraphQLError {
87 fn from(e: mongodb::error::Error) -> Self {
88 GraphQLError::Database(format!("MongoDB error: {}", e))
89 }
90}